home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 80 / CD Actual 80 Julio-Agosto 2003.iso / Linux / LinuxGazette / lg / issue14 / misc / supermount-0.4c-for-2.0.23.diff < prev    next >
Encoding:
Text File  |  2002-08-14  |  67.7 KB  |  2,360 lines

  1. Index: linux/Documentation/filesystems/supermount.txt
  2. diff -u linux/Documentation/filesystems/supermount.txt:1.1 linux/Documentation/filesystems/supermount.txt:1.1.6.1
  3. --- linux/Documentation/filesystems/supermount.txt:1.1    Mon Feb 26 17:55:03 1996
  4. +++ linux/Documentation/filesystems/supermount.txt    Sat Nov  9 20:35:00 1996
  5. @@ -0,0 +1,179 @@
  6. +Supermount README
  7. +=================
  8. +
  9. +For supermount v0.4c, on linux kernels 2.0.23 or later.
  10. +
  11. +Supermount is a pseudo-filesystem which manages filesystems on
  12. +removable media like floppy disks and CD-ROMs.  It aims to make
  13. +management of removable media as easy as it is under DOS.
  14. +
  15. +With supermount, you can change the disk in the drive whenever you
  16. +want (with the obvious exception that you shouldn't do it when the
  17. +filesystem is actively in use).  You don't need to "cd" out of the
  18. +directory first, and you don't need to tell the kernel what you're
  19. +doing --- supermount will detect the media change automatically.
  20. +
  21. +Supermount will automatically detect whether the media you are
  22. +mounting is read-write or readonly, and if you mount a write-protected
  23. +disk, then the subfs will be mounted as a readonly filesystem.
  24. +
  25. +Supermount detects when you have finished activity on the subfs, and
  26. +will flush all buffers to the disk before completing the operation.
  27. +So, if you copy a file onto a supermounted floppy disk, the data will
  28. +all be written to disk before the "cp" command finishes.  When the
  29. +command does complete, it will be safe to remove the disk.
  30. +
  31. +It is worth while defining what I mean by "activity" here.  The subfs
  32. +is active if there are any processes running which have a handle on a
  33. +non-directory inode on the subfs, or which have a file open on the
  34. +subfs (even if only for reading).  There is one important case which
  35. +does NOT count as activity: if you "cd" to a directory or a
  36. +subdirectory under the supermount mount point, then that reference
  37. +does not make the subfs active, and you can safely remove the disk.
  38. +
  39. +Yes, that's right.  You can "cd /floppy; ls" and get a listing of a
  40. +dos floppy.  Remove the disk, insert a new one, and "ls" will now list
  41. +the new contents.  Remove the disk altogether, and "ls" will give you
  42. +an I/O error.  Put in a new disk, and "ls" starts working again.  It
  43. +is NOT an error to remove a supermounted disk which is acting as the
  44. +current working directory for one or more processes!
  45. +
  46. +
  47. +The Superfilesystem and Subfilesystem concepts
  48. +----------------------------------------------
  49. +
  50. +Normally, when you mount a filesystem, you create a direct connection
  51. +between a mount point in the directory tree and a filesystem on a
  52. +block device.  Supermount adds an extra layer in between; with
  53. +supermount, you explicitly mount the pseudo-filesystem (the
  54. +"superfilesystem") on the mount point, and supermount then
  55. +automatically mounts the real filesystem (the "subfilesystem") on the
  56. +block device when needed.
  57. +
  58. +Running supermount
  59. +------------------
  60. +
  61. +To run supermount, compile and install a kernel with the supermount
  62. +patches and select "Y" to the question
  63. +
  64. +    Dynamic mounting of removable media?
  65. +
  66. +when you run "make config".  You set up a supermount filesystem with
  67. +the normal mount command, using the syntax:
  68. +
  69. +    mount -o <superfs-options>,--,<subfs-options> <dev> <mount-point>
  70. +
  71. +<dev> can be anything you want.  Using supermount, the block device
  72. +you are using is not physically mounted until there is a filesystem
  73. +access to the mount point, so the device specified on the command line
  74. +is ignored.  It is convenient just to specify the mount point as the
  75. +device as well, so that you give the mount point twice on the command
  76. +line.  Doing this reduces the chance that the mount program will
  77. +confuse the mount point with some other mount point defined in
  78. +/etc/fstab.
  79. +
  80. +The way you specify the location of the block device you want to mount
  81. +is by providing the <superfs-options> field, where the following
  82. +options are currently recognised:
  83. +
  84. +* subfs=<filesystem-type>        [default is "msdos"]
  85. +
  86. +    Specify the subfilesystem type.  "msdos" and "iso9660" have
  87. +been tested, but any block-device filesystem should work with one
  88. +important restriction: the filesystem must NOT try to write to the
  89. +device when you unmount it.  This is because supermount doesn't know
  90. +in advance when it will have to unmount the subfs, so it doesn't try
  91. +to do so until it detects that the media has been changed.  By this
  92. +time it is too late to write to the device!
  93. +
  94. +    If you mount supermount as a readonly filesystem ("mount -r"
  95. +or "mount -o ro"), then you won't have this problem.  Otherwise, you
  96. +will not be able to use the ext2fs or minix filesystems with
  97. +supermount.  This will hopefully be addressed in a future release of
  98. +supermount.
  99. +
  100. +* dev=<block-device>            [default is "/dev/fd0"]
  101. +
  102. +    Specify the block device on which the subfs is to be mounted.
  103. +
  104. +* debug
  105. +
  106. +    Enable debugging code in the supermount filesystem, if
  107. +the debug option was enabled at compile time.  By default, debugging
  108. +code is compiled into the kernel but is disabled until a debug mount
  109. +option is seen.
  110. +
  111. +* '--'
  112. +
  113. +    All options after the option string '--' will be passed
  114. +directly to the subfilesystem when it gets mounted.
  115. +
  116. +
  117. +Here is an example of supermount options, taken directly out of my
  118. +current /etc/fstab:
  119. +
  120. +/floppy /floppy    supermount    --,gid=51,conv=binary    0 0
  121. +/cd    /cd    supermount    ro,fs=iso9660,dev=/dev/hdd,--,conv=binary 0 0
  122. +
  123. +This tells supermount to manage a msdos filesystem on /dev/fd0 mounted
  124. +at /floppy (msdos and /dev/fd0 are defaults for supermount), with the
  125. +msdos filesystem getting the options "gid=51,conv=binary".  My cdrom
  126. +on /dev/hdd is similarly mounted on /cd.
  127. +
  128. +
  129. +Caveats and Provisos
  130. +--------------------
  131. +
  132. +There are still some limitations to the current version of
  133. +supermount.  I hope to overcome these shortly in future releases, but
  134. +for now, be aware that:
  135. +
  136. +* You can only specify one filesystem type on the mount command line.
  137. +  Supermount cannot yet autodetect the type of filesystem you supply.
  138. +
  139. +* With the 2.0 kernel, CDROM door locking has been made much more
  140. +  aggressive.  You will probably find that once supermount has mounted
  141. +  your disk, you cannot unmount it again.  Not helpful!
  142. +
  143. +* The only filesystem which is supported read/write with supermount is
  144. +  msdos.  The msdos filesystem has the special characteristic that it
  145. +  never has to access the disk when you unmount it, so supermount can
  146. +  safely defer the unmounting until after the disk is removed.  That
  147. +  doesn't work so well for filesystems such as ext2fs which try to
  148. +  write to the filesystem when it is unmounted.
  149. +
  150. +Problems 2) and 3) are being solved by a development patch to support
  151. +unmount-on-timeout, which will do a full unmount of the media after
  152. +half a second or so of inactivity, releasing the volume for removal.
  153. +Problem 1) has been addressed by a contributed patch which I hope to
  154. +integrate shortly.  As usual, watch this space, and anybody who I've
  155. +got on my list of supermount users will be emailed with further
  156. +developments!
  157. +
  158. +
  159. +Enjoy supermount.  I hope you find it useful --- I certainly find it
  160. +extremely convenient.  Send any comments, bug-fixes or bug-reports,
  161. +suggestions and success stories to sct@dcs.ed.ac.uk.  Flames to
  162. +/dev/null, please!
  163. +
  164. +Cheers,
  165. + Stephen.
  166. +--
  167. +
  168. +================================================================
  169. +Changes for v0.4c:
  170. +Works against linux-2.0.23.
  171. +Updated documentation.
  172. +Fixed problem with default root inode mode.
  173. +
  174. +Changes for v0.4:
  175. +Performance tuning only.  Read-only operations like "find" should now
  176. +be MUCH faster.
  177. +
  178. +Changes for v0.3:
  179. +Fixed supermount_create bug; now returns a properly attached
  180. +superinode.
  181. +
  182. +Changes for v0.2:
  183. +Improved device invalidation code, so CD-ROMs work now.
  184. +
  185. Index: linux/fs/Config.in
  186. diff -u linux/fs/Config.in:1.5 linux/fs/Config.in:1.5.2.1
  187. --- linux/fs/Config.in:1.5    Wed Nov  6 23:16:50 1996
  188. +++ linux/fs/Config.in    Sat Nov  9 17:26:20 1996
  189. @@ -6,6 +6,7 @@
  190.  
  191.  bool     'Quota support' CONFIG_QUOTA
  192.  bool     'Mandatory lock support' CONFIG_LOCK_MANDATORY
  193. +bool     'Supermount removable media support' CONFIG_SUPERMOUNT
  194.  tristate 'Minix fs support' CONFIG_MINIX_FS
  195.  tristate 'Extended fs support' CONFIG_EXT_FS
  196.  tristate 'Second extended fs support' CONFIG_EXT2_FS
  197. Index: linux/fs/Makefile
  198. diff -u linux/fs/Makefile:1.4 linux/fs/Makefile:1.4.4.1
  199. --- linux/fs/Makefile:1.4    Wed May 15 14:12:18 1996
  200. +++ linux/fs/Makefile    Sat Nov  9 17:26:21 1996
  201. @@ -17,7 +17,7 @@
  202.  
  203.  MOD_LIST_NAME := FS_MODULES
  204.  ALL_SUB_DIRS = minix ext ext2 fat msdos vfat proc isofs nfs xiafs umsdos \
  205. -        hpfs sysv smbfs ncpfs ufs affs
  206. +        hpfs sysv smbfs ncpfs ufs affs supermount
  207.  
  208.  ifeq ($(CONFIG_QUOTA),y)
  209.  O_OBJS += dquot.o
  210. @@ -139,6 +139,14 @@
  211.    ifeq ($(CONFIG_HPFS_FS),m)
  212.    MOD_SUB_DIRS += hpfs
  213.    endif
  214. +endif
  215. +
  216. +ifeq ($(CONFIG_SUPERMOUNT),y)
  217. +SUB_DIRS += supermount
  218. +#else
  219. +#  ifeq ($(CONFIG_SUPERMOUNT),m)
  220. +#  MOD_SUB_DIRS += supermount
  221. +#  endif
  222.  endif
  223.  
  224.  ifeq ($(CONFIG_UFS_FS),y)
  225. Index: linux/fs/devices.c
  226. diff -u linux/fs/devices.c:1.3 linux/fs/devices.c:1.3.4.1
  227. --- linux/fs/devices.c:1.3    Wed May 15 14:12:20 1996
  228. +++ linux/fs/devices.c    Sat Nov  9 17:26:22 1996
  229. @@ -187,15 +187,14 @@
  230.  }
  231.  
  232.  /*
  233. - * This routine checks whether a removable media has been changed,
  234. - * and invalidates all buffer-cache-entries in that case. This
  235. - * is a relatively slow routine, so we have to try to minimize using
  236. - * it. Thus it is called only upon a 'mount' or 'open'. This
  237. - * is the best way of combining speed and utility, I think.
  238. - * People changing diskettes in the middle of an operation deserve
  239. - * to loose :-)
  240. - */
  241. -int check_disk_change(kdev_t dev)
  242. + * These routines checks whether a removable media has been changed,
  243. + * and (for check_disk_change only) invalidate all
  244. + * buffer-cache-entries in that case. This is a relatively slow
  245. + * routine, so we have to try to minimize using it. Thus it is called
  246. + * only upon a 'mount' or 'open'. This is the best way of combining
  247. + * speed and utility, I think.  People changing diskettes in the
  248. + * middle of an operation deserve to loose :-) */
  249. +int query_disk_change(kdev_t dev)
  250.  {
  251.      int i;
  252.      struct file_operations * fops;
  253. @@ -208,17 +207,37 @@
  254.      if (!fops->check_media_change(dev))
  255.          return 0;
  256.  
  257. +    return 1;
  258. +}
  259. +
  260. +int check_disk_change(kdev_t dev)
  261. +{
  262. +    if (!query_disk_change(dev))
  263. +        return 0;
  264.      printk(KERN_DEBUG "VFS: Disk change detected on device %s\n",
  265.          kdevname(dev));
  266. +    invalidate_media(dev);
  267. +    return 1;
  268. +}
  269. +
  270. +void invalidate_media(kdev_t dev) 
  271. +{
  272. +    int i;
  273. +    struct file_operations * fops;
  274. +    
  275. +    i = MAJOR(dev);
  276. +    if (i >= MAX_BLKDEV)
  277. +        return;
  278. +    fops = blkdevs[i].fops;
  279.      for (i=0 ; i<NR_SUPER ; i++)
  280.          if (super_blocks[i].s_dev == dev)
  281.              put_super(super_blocks[i].s_dev);
  282.      invalidate_inodes(dev);
  283.      invalidate_buffers(dev);
  284.  
  285. -    if (fops->revalidate)
  286. +    if (fops && fops->revalidate)
  287.          fops->revalidate(dev);
  288. -    return 1;
  289. +    return;
  290.  }
  291.  
  292.  /*
  293. Index: linux/fs/filesystems.c
  294. diff -u linux/fs/filesystems.c:1.3 linux/fs/filesystems.c:1.3.4.1
  295. --- linux/fs/filesystems.c:1.3    Sat Apr 27 17:06:29 1996
  296. +++ linux/fs/filesystems.c    Sat Nov  9 17:26:22 1996
  297. @@ -9,6 +9,7 @@
  298.  #include <linux/config.h>
  299.  #include <linux/fs.h>
  300.  
  301. +#include <linux/supermount_fs.h>
  302.  #include <linux/minix_fs.h>
  303.  #include <linux/ext_fs.h>
  304.  #include <linux/ext2_fs.h>
  305. @@ -39,6 +40,11 @@
  306.      callable = 0;
  307.  
  308.      device_setup();
  309. +
  310. +#ifdef CONFIG_SUPERMOUNT
  311. +    register_filesystem(&(struct file_system_type)
  312. +        {supermount_read_super, "supermount", 0, NULL});
  313. +#endif
  314.  
  315.      binfmt_setup();
  316.  
  317. Index: linux/fs/inode.c
  318. diff -u linux/fs/inode.c:1.5 linux/fs/inode.c:1.5.2.1
  319. --- linux/fs/inode.c:1.5    Wed Nov  6 23:16:52 1996
  320. +++ linux/fs/inode.c    Sat Nov  9 17:26:22 1996
  321. @@ -219,6 +219,8 @@
  322.          if (inode == mount_root && inode->i_count ==
  323.              (inode->i_mount != inode ? 1 : 2))
  324.              continue;
  325. +        if (IS_UNBOUND(inode))
  326. +            continue;
  327.          return 0;
  328.      }
  329.      return 1;
  330. @@ -254,6 +256,9 @@
  331.      inode->i_lock = 1;    
  332.      inode->i_sb->s_op->write_inode(inode);
  333.      unlock_inode(inode);
  334. +    if (inode->i_shadow && inode->i_shadow->i_shadow_op && 
  335. +        inode->i_shadow->i_shadow_op->write)
  336. +        inode->i_shadow->i_shadow_op->write(inode->i_shadow);
  337.  }
  338.  
  339.  static inline void read_inode(struct inode * inode)
  340. @@ -414,15 +419,24 @@
  341.      }
  342.  }
  343.  
  344. +static inline void release_shadow(struct inode * inode) {
  345. +    /* Shadow-release should be atomic. */
  346. +    struct inode * tmp;
  347. +    tmp = inode->i_shadow;
  348. +    inode->i_shadow = 0;
  349. +}
  350. +
  351.  void iput(struct inode * inode)
  352.  {
  353. +    struct inode * shadow;
  354. +
  355.      if (!inode)
  356.          return;
  357.      wait_on_inode(inode);
  358.      if (!inode->i_count) {
  359.          printk("VFS: iput: trying to free free inode\n");
  360.          printk("VFS: device %s, inode %lu, mode=0%07o\n",
  361. -            kdevname(inode->i_rdev), inode->i_ino, inode->i_mode);
  362. +            kdevname(inode->i_dev), inode->i_ino, inode->i_mode);
  363.          return;
  364.      }
  365.      if (inode->i_pipe)
  366. @@ -441,9 +455,22 @@
  367.      }
  368.  
  369.      if (inode->i_sb && inode->i_sb->s_op && inode->i_sb->s_op->put_inode) {
  370. +        shadow = inode->i_shadow;
  371.          inode->i_sb->s_op->put_inode(inode);
  372. -        if (!inode->i_nlink)
  373. +        if (!inode->i_nlink) {
  374. +            /* The inode should have been cleared, so we
  375. +                           don't reset inode->i_shadow here. */
  376. +            if (shadow) {
  377. +            if (shadow->i_shadow_op && 
  378. +                shadow->i_shadow_op->release)
  379. +                shadow->i_shadow_op->release(shadow);
  380. +            iput (shadow);
  381. +            }
  382. +            /* put_inode should do a clear_inode() if the
  383. +               inode is unlinked, so don't bother falling
  384. +               through... */
  385.              return;
  386. +        }
  387.      }
  388.  
  389.      if (inode->i_dirt) {
  390. @@ -473,6 +500,14 @@
  391.      }
  392.  
  393.      nr_free_inodes++;
  394. +    shadow = inode->i_shadow;
  395. +    inode->i_shadow = 0;
  396. +    if (shadow) {
  397. +        if (shadow->i_shadow_op && 
  398. +            shadow->i_shadow_op->release)
  399. +            shadow->i_shadow_op->release(shadow);
  400. +        iput (shadow);
  401. +    }
  402.      return;
  403.  }
  404.  
  405. Index: linux/fs/open.c
  406. diff -u linux/fs/open.c:1.4 linux/fs/open.c:1.4.2.1
  407. --- linux/fs/open.c:1.4    Wed Nov  6 23:16:53 1996
  408. +++ linux/fs/open.c    Sat Nov  9 17:26:22 1996
  409. @@ -523,6 +523,10 @@
  410.              goto cleanup_inode;
  411.      }
  412.  
  413. +    if (inode->i_shadow && inode->i_shadow->i_shadow_op &&
  414. +        inode->i_shadow->i_shadow_op->open)
  415. +        inode->i_shadow->i_shadow_op->open(inode->i_shadow, flag);
  416. +
  417.      f->f_inode = inode;
  418.      f->f_pos = 0;
  419.      f->f_reada = 0;
  420. Index: linux/fs/super.c
  421. diff -u linux/fs/super.c:1.9 linux/fs/super.c:1.9.2.1
  422. --- linux/fs/super.c:1.9    Wed Nov  6 23:16:54 1996
  423. +++ linux/fs/super.c    Sat Nov  9 17:26:23 1996
  424. @@ -628,21 +628,12 @@
  425.   * functions, they should be faked here.  -- jrs
  426.   */
  427.  
  428. -asmlinkage int sys_umount(char * name)
  429. +int do_umounti(struct inode * inode)
  430.  {
  431. -    struct inode * inode;
  432.      kdev_t dev;
  433.      int retval;
  434.      struct inode dummy_inode;
  435.  
  436. -    if (!suser())
  437. -        return -EPERM;
  438. -    retval = namei(name, &inode);
  439. -    if (retval) {
  440. -        retval = lnamei(name, &inode);
  441. -        if (retval)
  442. -            return retval;
  443. -    }
  444.      if (S_ISBLK(inode->i_mode)) {
  445.          dev = inode->i_rdev;
  446.          if (IS_NODEV(inode)) {
  447. @@ -681,50 +672,55 @@
  448.      return 0;
  449.  }
  450.  
  451. -/*
  452. - * do_mount() does the actual mounting after sys_mount has done the ugly
  453. - * parameter parsing. When enough time has gone by, and everything uses the
  454. - * new mount() parameters, sys_mount() can then be cleaned up.
  455. +asmlinkage int sys_umount(char * name)
  456. +{
  457. +    struct inode * inode;
  458. +    int retval;
  459. +
  460. +    if (!suser())
  461. +        return -EPERM;
  462. +    retval = namei(name,&inode);
  463. +    if (retval) {
  464. +        retval = lnamei(name,&inode);
  465. +        if (retval)
  466. +            return retval;
  467. +    }
  468. +    return do_umounti(inode);
  469. +}
  470. +
  471. +/* 
  472. + * do_mountdev() does the actual mounting after sys_mount has done the
  473. + * ugly parameter parsing. When enough time has gone by, and
  474. + * everything uses the new mount() parameters, sys_mount() can then be
  475. + * cleaned up.
  476.   *
  477.   * We cannot mount a filesystem if it has active, used, or dirty inodes.
  478.   * We also have to flush all inode-data for this device, as the new mount
  479. - * might need new info.
  480. + * might need new info.  
  481.   */
  482.  
  483. -int do_mount(kdev_t dev, const char * dev_name, const char * dir_name, const char * type, int flags, void * data)
  484. +int do_mountdev(kdev_t dev, 
  485. +        struct inode *dir_i,
  486. +        const char * dev_name,
  487. +        const char * dir_name,
  488. +        const char * type, 
  489. +        int flags,
  490. +        void * data)
  491.  {
  492. -    struct inode * dir_i;
  493.      struct super_block * sb;
  494.      struct vfsmount *vfsmnt;
  495. -    int error;
  496.  
  497. -    if (!(flags & MS_RDONLY) && dev && is_read_only(dev))
  498. -        return -EACCES;
  499. -        /*flags |= MS_RDONLY;*/
  500. -    error = namei(dir_name, &dir_i);
  501. -    if (error)
  502. -        return error;
  503. -    if (dir_i->i_count != 1 || dir_i->i_mount) {
  504. -        iput(dir_i);
  505. +    if (dir_i->i_count != 1 || dir_i->i_mount)
  506.          return -EBUSY;
  507. -    }
  508. -    if (!S_ISDIR(dir_i->i_mode)) {
  509. -        iput(dir_i);
  510. +    if (!S_ISDIR(dir_i->i_mode))
  511.          return -ENOTDIR;
  512. -    }
  513. -    if (!fs_may_mount(dev)) {
  514. -        iput(dir_i);
  515. +    if (!fs_may_mount(dev))
  516.          return -EBUSY;
  517. -    }
  518.      sb = read_super(dev,type,flags,data,0);
  519. -    if (!sb) {
  520. -        iput(dir_i);
  521. +    if (!sb)
  522.          return -EINVAL;
  523. -    }
  524. -    if (sb->s_covered) {
  525. -        iput(dir_i);
  526. +    if (sb->s_covered)
  527.          return -EBUSY;
  528. -    }
  529.      vfsmnt = add_vfsmnt(dev, dev_name, dir_name);
  530.      if (vfsmnt) {
  531.          vfsmnt->mnt_sb = sb;
  532. @@ -736,6 +732,26 @@
  533.  }
  534.  
  535.  
  536. +int do_mount(kdev_t dev,
  537. +         const char * dev_name,
  538. +         const char * dir_name,
  539. +         const char * type,
  540. +         int flags,
  541. +         void * data)
  542. +{
  543. +    int error;
  544. +    struct inode * dir_i;
  545. +
  546. +    error = namei(dir_name, &dir_i);
  547. +    if (error)
  548. +        return error;
  549. +    error = do_mountdev(dev, dir_i, dev_name, dir_name, type, flags, data);
  550. +    if (error)
  551. +        iput(dir_i);
  552. +    return error;
  553. +}
  554. +
  555. +  
  556.  /*
  557.   * Alters the mount flags of a mounted file system. Only the mount point
  558.   * is used as a reference - file system type and the device are ignored.
  559. @@ -794,14 +810,23 @@
  560.      if (!data)
  561.          return 0;
  562.  
  563. -    vma = find_vma(current->mm, (unsigned long) data);
  564. -    if (!vma || (unsigned long) data < vma->vm_start)
  565. -        return -EFAULT;
  566. -    if (!(vma->vm_flags & VM_READ))
  567. -        return -EFAULT;
  568. -    i = vma->vm_end - (unsigned long) data;
  569. -    if (PAGE_SIZE <= (unsigned long) i)
  570. +    /* 
  571. +     * Supermount calls the mount code from kernel space, so don't
  572. +     * validate the mount data if it is already in kernel address
  573. +     * space.
  574. +     */
  575. +    if (get_fs() != get_ds()) {
  576. +        vma = find_vma(current->mm, (unsigned long) data);
  577. +        if (!vma || (unsigned long) data < vma->vm_start)
  578. +            return -EFAULT;
  579. +        if (!(vma->vm_flags & VM_READ))
  580. +            return -EFAULT;
  581. +        i = vma->vm_end - (unsigned long) data;
  582. +        if (PAGE_SIZE <= (unsigned long) i)
  583. +            i = PAGE_SIZE-1;
  584. +    } else {
  585.          i = PAGE_SIZE-1;
  586. +    }
  587.      if (!(page = __get_free_page(GFP_KERNEL))) {
  588.          return -ENOMEM;
  589.      }
  590. @@ -825,15 +850,10 @@
  591.   * version that didn't understand them.
  592.   */
  593.  asmlinkage int sys_mount(char * dev_name, char * dir_name, char * type,
  594. -    unsigned long new_flags, void * data)
  595. +             unsigned long new_flags, void * data)
  596.  {
  597. -    struct file_system_type * fstype;
  598. -    struct inode * inode;
  599. -    struct file_operations * fops;
  600. -    kdev_t dev;
  601. +    struct inode * dir_inode;
  602.      int retval;
  603. -    const char * t;
  604. -    unsigned long flags = 0;
  605.      unsigned long page = 0;
  606.  
  607.      if (!suser())
  608. @@ -849,6 +869,29 @@
  609.          free_page(page);
  610.          return retval;
  611.      }
  612. +    retval = namei(dir_name, &dir_inode);
  613. +    if (retval)
  614. +        return retval;
  615. +    retval = do_mounti(dir_inode,dir_name,dev_name,type,new_flags,data);
  616. +    if (retval)
  617. +        iput(dir_inode);
  618. +    return retval;
  619. +}
  620. +
  621. +/* Mount on a given inode.  Don't iput() the mount point! */
  622. +int do_mounti(struct inode * dir_inode, const char * dir_name, 
  623. +          const char * dev_name, const char * type, 
  624. +          unsigned long new_flags, const void * data)
  625. +{
  626. +    struct file_system_type * fstype;
  627. +    struct inode * inode;
  628. +    struct file_operations * fops;
  629. +    dev_t dev;
  630. +    int retval;
  631. +    const char * t;
  632. +    unsigned long flags = 0;
  633. +    unsigned long page = 0;
  634. +
  635.      retval = copy_mount_options (type, &page);
  636.      if (retval < 0)
  637.          return retval;
  638. @@ -906,7 +949,8 @@
  639.              return retval;
  640.          }
  641.      }
  642. -    retval = do_mount(dev,dev_name,dir_name,t,flags,(void *) page);
  643. +    retval = do_mountdev(dev,dir_inode,dev_name,dir_name,
  644. +                 t,flags,(void *) page);
  645.      free_page(page);
  646.      if (retval && fops && fops->release)
  647.          fops->release(inode, NULL);
  648. Index: linux/fs/supermount/Makefile
  649. diff -u linux/fs/supermount/Makefile:1.1 linux/fs/supermount/Makefile:1.1.6.1
  650. --- linux/fs/supermount/Makefile:1.1    Mon Feb 26 17:55:15 1996
  651. +++ linux/fs/supermount/Makefile    Sat Nov  9 17:27:24 1996
  652. @@ -0,0 +1,14 @@
  653. +#
  654. +# Makefile for the linux supermounting routines.
  655. +#
  656. +# Note! Dependencies are done automagically by 'make dep', which also
  657. +# removes any old dependencies. DON'T put your own dependencies here
  658. +# unless it's something special (ie not a .c file).
  659. +#
  660. +# Note 2! The CFLAGS definitions are now in the main makefile...
  661. +
  662. +O_TARGET := supermount.o
  663. +O_OBJS     := dir.o inode.o namei.o super.o
  664. +M_OBJS     := $(O_TARGET)
  665. +
  666. +include $(TOPDIR)/Rules.make
  667. Index: linux/fs/supermount/TODO
  668. diff -u linux/fs/supermount/TODO:1.1 linux/fs/supermount/TODO:1.1.6.1
  669. --- linux/fs/supermount/TODO:1.1    Mon Feb 26 17:55:15 1996
  670. +++ linux/fs/supermount/TODO    Sat Nov  9 17:27:24 1996
  671. @@ -0,0 +1,40 @@
  672. +Notes:
  673. +
  674. +TODO:
  675. +
  676. +  Supermount directory inodes do auto-remount as root of the subfs.  Make
  677. +  a mount option to restrict this behaviour to the root?
  678. +
  679. +  Make supermount_attach a special case of read_hidden_inode, not the other
  680. +  way around.
  681. +
  682. +  Replace shadow inodes with shadow superblock?  Do release that way?
  683. +
  684. +  Unmount on suspend?  OK iff inode numbers on open directories will
  685. +  be the same next time around!  (Normally true.)  Bad for performance, but
  686. +  maybe necessary for ext2fs, for example.
  687. +
  688. +Done:::
  689. +
  690. +  Sigh.  We can't rely on the one-to-one mapping of superinode to
  691. +  subinode i_ino numbers any more.  Why not?  Well, what happens if we
  692. +  remove and remount a medium?  We can end up with one process holding
  693. +  a handle to an old, obsolete superinode, and a new process opening a
  694. +  subinode with the same i_ino.  Well, we can do a quadratic hash on
  695. +  the superinode numbers to avoid collisions.  Think about this!
  696. +
  697. +  * What happens when we do get an inode collision?  We rehash to make
  698. +    another superinode the current one; the old inode remains as a
  699. +    placeholder.  But then, what if the old inode becomes released?  A
  700. +    subsequent attach may place the subinode under that old inode
  701. +    instead of the new superinode.
  702. +
  703. +    OK: There is only ever one hidden/shadow connection between super
  704. +    and sub inodes.  If that is broken, we can reestablish it from any
  705. +    superinode we want to.  Previously valid superinodes will have to
  706. +    rely on i_subino to get to their subinode (the subinode i_ino will
  707. +    NOT change behind our backs, hopefully).  Such mappings should
  708. +    only ever be one way, from superinode to subinode, done by
  709. +    subiget().
  710. +
  711. +  Special handling of root directory to do auto remount.
  712. Index: linux/fs/supermount/dir.c
  713. diff -u linux/fs/supermount/dir.c:1.1 linux/fs/supermount/dir.c:1.1.6.1
  714. --- linux/fs/supermount/dir.c:1.1    Mon Feb 26 17:55:15 1996
  715. +++ linux/fs/supermount/dir.c    Sat Nov  9 17:27:24 1996
  716. @@ -0,0 +1,97 @@
  717. +/*
  718. + *  linux/fs/supermount/dir.c
  719. + *
  720. + *  Copyright (C) 1995
  721. + *  Stephen Tweedie (sct@dcs.ed.ac.uk)
  722. + *
  723. + *  from
  724. + *
  725. + *  linux/fs/minix/dir.c
  726. + *  Copyright (C) 1991, 1992  Linus Torvalds
  727. + *
  728. + *  and
  729. + *
  730. + *  linux/fs/ext2/dir.c
  731. + *  Copyright (C) 1992, 1993, 1994, 1995  Remy Card
  732. + */
  733. +
  734. +#include <asm/segment.h>
  735. +
  736. +#include <linux/errno.h>
  737. +#include <linux/kernel.h>
  738. +#include <linux/fs.h>
  739. +#include <linux/supermount_fs.h>
  740. +#include <linux/stat.h>
  741. +
  742. +static int supermount_dir_open (struct inode *, struct file *);
  743. +
  744. +static struct file_operations supermount_dir_operations = {
  745. +    NULL,            /* lseek - default */
  746. +    NULL,            /* read */
  747. +    NULL,            /* write - bad */
  748. +    NULL,            /* readdir */
  749. +    NULL,            /* select - default */
  750. +    NULL,            /* ioctl */
  751. +    NULL,            /* mmap */
  752. +    supermount_dir_open,    /* Redirect to the subfs readdir() code */
  753. +    NULL,            /* no special release code */
  754. +    NULL,            /* fsync */
  755. +    NULL,            /* fasync */
  756. +    NULL,            /* check_media_change */
  757. +    NULL            /* revalidate */
  758. +};
  759. +
  760. +/*
  761. + * directories can handle most operations...  supermount/namei.c just
  762. + * passes them through to the underlying subfs, except for lookup().
  763. + */
  764. +struct inode_operations supermount_dir_iops = {
  765. +    &supermount_dir_operations,    /* default directory file-ops */
  766. +    supermount_create,        /* create */
  767. +    supermount_lookup,        /* lookup */
  768. +    supermount_link,        /* link */
  769. +    supermount_unlink,        /* unlink */
  770. +    supermount_symlink,        /* symlink */
  771. +    supermount_mkdir,        /* mkdir */
  772. +    supermount_rmdir,        /* rmdir */
  773. +    supermount_mknod,        /* mknod */
  774. +    supermount_rename,        /* rename */
  775. +    NULL,                /* readlink */
  776. +    NULL,                /* follow_link */
  777. +    NULL,                /* bmap */
  778. +    NULL,                /* truncate */
  779. +    supermount_permission,        /* permission */
  780. +    NULL                /* smap */
  781. +};
  782. +
  783. +
  784. +/* When we open() a directory (for readdir), just rewrite the file
  785. +   struct to point to the subfs inode, and let it handle all the
  786. +   work. */
  787. +static int supermount_dir_open (struct inode * inode, struct file * file)
  788. +{
  789. +    struct inode * subi;
  790. +    int rc;
  791. +    
  792. +    if (file->f_mode & 2)
  793. +        return -EPERM;
  794. +
  795. +    supermount_debug ("dir_open inode %ld\n", inode->i_ino);
  796. +    
  797. +    subi = subiget(inode);
  798. +    if (!subi)
  799. +        return -ENOENT;
  800. +
  801. +    file->f_inode = subi;
  802. +    file->f_op = subi->i_op ? subi->i_op->default_file_ops : NULL;
  803. +    if (file->f_op && file->f_op->open) {
  804. +        rc = file->f_op->open(subi, file);
  805. +        if (rc) {
  806. +            iput(subi);
  807. +            return rc;
  808. +        }
  809. +    }
  810. +    iput(inode);
  811. +    return 0;
  812. +}
  813. +
  814. Index: linux/fs/supermount/file.c
  815. diff -u linux/fs/supermount/file.c:1.1 linux/fs/supermount/file.c:1.1.6.1
  816. --- linux/fs/supermount/file.c:1.1    Mon Feb 26 17:55:15 1996
  817. +++ linux/fs/supermount/file.c    Sat Nov  9 17:27:25 1996
  818. @@ -0,0 +1,21 @@
  819. +/*
  820. + *  linux/fs/supermount/file.c
  821. + *
  822. + *  Copyright (C) 1995
  823. + *  Stephen Tweedie (sct@dcs.ed.ac.uk)
  824. + *
  825. + */
  826. +
  827. +#include <asm/segment.h>
  828. +#include <asm/system.h>
  829. +
  830. +#include <linux/errno.h>
  831. +#include <linux/fs.h>
  832. +#include <linux/supermount_fs.h>
  833. +#include <linux/fcntl.h>
  834. +#include <linux/sched.h>
  835. +#include <linux/stat.h>
  836. +#include <linux/locks.h>
  837. +
  838. +static void supermount_inode_release (struct inode *);
  839. +
  840. Index: linux/fs/supermount/inode.c
  841. diff -u linux/fs/supermount/inode.c:1.1 linux/fs/supermount/inode.c:1.1.6.1
  842. --- linux/fs/supermount/inode.c:1.1    Mon Feb 26 17:55:16 1996
  843. +++ linux/fs/supermount/inode.c    Sat Nov  9 17:27:25 1996
  844. @@ -0,0 +1,380 @@
  845. +/*
  846. + *  linux/fs/supermount/inode.c
  847. + *
  848. + *  Copyright (C) 1995
  849. + *  Stephen Tweedie (sct@dcs.ed.ac.uk)
  850. + *
  851. + *  from
  852. + *
  853. + *  linux/fs/minix/inode.c
  854. + *  Copyright (C) 1991, 1992  Linus Torvalds
  855. + *
  856. + *  and
  857. + *
  858. + *  linux/fs/ext2/inode.c
  859. + *  Copyright (C) 1992, 1993, 1994, 1995  Remy Card
  860. + *  and           1993  Stephen Tweedie
  861. + */
  862. +
  863. +#include <asm/segment.h>
  864. +#include <asm/system.h>
  865. +
  866. +#include <linux/errno.h>
  867. +#include <linux/fs.h>
  868. +#include <linux/supermount_fs.h>
  869. +#include <linux/sched.h>
  870. +#include <linux/stat.h>
  871. +#include <linux/string.h>
  872. +#include <linux/locks.h>
  873. +#include <linux/mm.h>
  874. +
  875. +static void read_hidden_inode (struct inode *);
  876. +static void supermount_inode_open (struct inode *, int);
  877. +static void supermount_inode_write (struct inode *);
  878. +static void supermount_inode_release (struct inode *);
  879. +
  880. +/* Deal with the shadow interface.  Whenever a subfs inode is
  881. +   released, break the bi-directional link between them, and close and
  882. +   iput the supermount inode.  */
  883. +
  884. +struct inode_shadow_operations supermount_shadow_iops = {
  885. +    supermount_inode_open,
  886. +    supermount_inode_write,
  887. +    supermount_inode_release,
  888. +};
  889. +
  890. +void supermount_inode_open (struct inode *inode, int flag)
  891. +{
  892. +    if (flag & 2)
  893. +        mark_subfs_dirty(inode->i_sb);
  894. +}
  895. +
  896. +void supermount_inode_write (struct inode *inode)
  897. +{
  898. +    mark_subfs_dirty(inode->i_sb);
  899. +}
  900. +
  901. +void supermount_inode_release (struct inode *inode)
  902. +{
  903. +    supermount_debug ("inode = %ld\n", inode->i_ino);
  904. +    if (inode->u.supermount_i.i_hidden)
  905. +        supermount_debug("subinode = %ld\n", 
  906. +                 inode->u.supermount_i.i_hidden->i_ino);
  907. +    
  908. +    inode->u.supermount_i.i_hidden = NULL;
  909. +    supermount_iclose(inode);
  910. +}
  911. +
  912. +
  913. +/* Do an iget on the appropriate subfs inode */
  914. +struct inode * subiget(struct inode * inode) 
  915. +{
  916. +    struct inode * tmp;
  917. +    supermount_debug("subiget inode %ld\n", inode->i_ino);
  918. +
  919. +    if (!S_ISDIR(inode->i_mode))
  920. +        return 0;
  921. +    if (supermount_media_check(inode->i_sb)) {
  922. +        supermount_debug("media is invalid\n");
  923. +        return 0;
  924. +    }
  925. +    
  926. +    if (inode_is_obsolete(inode)) {
  927. +        /* For obsolete directory with new mounted media ---
  928. +                   return the new root subinode. */
  929. +        if (inode->u.supermount_i.i_hidden) 
  930. +            supermount_panic (inode->i_sb, "subiget", 
  931. +                      "Hidden inode on obsolete inode %ld",
  932. +                      inode->i_ino);
  933. +        tmp = inode->i_sb->u.supermount_sb.s_subfs->s_mounted;
  934. +        inode->u.supermount_i.i_subino = tmp->i_ino;
  935. +        tmp->i_count++;
  936. +        supermount_debug("mapping obsolete inode %ld to "
  937. +                 "subroot inode %ld\n",
  938. +                 inode->i_ino, tmp->i_ino);
  939. +        return tmp;
  940. +    }
  941. +    
  942. +    if (inode->u.supermount_i.i_hidden) {
  943. +        inode->u.supermount_i.i_hidden->i_count++;
  944. +        supermount_debug("inode %ld/%ld, found hidden, "
  945. +                 "count now %d/%d\n",
  946. +                 inode->i_ino,
  947. +                 inode->u.supermount_i.i_hidden->i_ino,
  948. +                 inode->i_count,
  949. +                 inode->u.supermount_i.i_hidden->i_count);
  950. +        return inode->u.supermount_i.i_hidden;
  951. +    }
  952. +    read_hidden_inode(inode);
  953. +    if (!inode->u.supermount_i.i_hidden) {
  954. +        supermount_debug("inode %ld, no subinode, count=%d\n",
  955. +                 inode->i_ino, inode->i_count);
  956. +        return 0;
  957. +    }
  958. +    
  959. +    supermount_debug("inode %ld/%ld, found new, "
  960. +             "count now %d/%d\n",
  961. +             inode->i_ino,
  962. +             inode->u.supermount_i.i_hidden->i_ino,
  963. +             inode->i_count,
  964. +             inode->u.supermount_i.i_hidden->i_count);
  965. +    return inode->u.supermount_i.i_hidden;
  966. +}
  967. +
  968. +/* We sometimes do a lookup on a subinode and want to get back a
  969. +   superinode in return, with a single iget() outstanding on both (not
  970. +   counting the i_shadow reference).  supermount_attach generates the
  971. +   superinode for a given subinode. */
  972. +struct inode * supermount_attach(struct super_block *sb, struct inode *inode) 
  973. +{
  974. +    struct inode *tmp;
  975. +    unsigned long new_ino, incr=1237;
  976. +    
  977. +    supermount_debug ("inode = %ld\n", inode->i_ino);
  978. +    
  979. +    if (inode->i_shadow) {
  980. +        supermount_debug ("return existing shadow %ld, count %d/%d\n",
  981. +                  inode->i_shadow->i_ino,
  982. +                  inode->i_shadow->i_count, inode->i_count);
  983. +        inode->i_shadow->i_count++;
  984. +        return inode->i_shadow;
  985. +    }
  986. +    
  987. +    /* The rules are a little different at the root. */
  988. +    if (inode == sb->u.supermount_sb.s_subfs->s_mounted) {
  989. +        tmp = sb->s_mounted;
  990. +        supermount_debug ("return existing superfs root %ld, "
  991. +                  "count %d/%d\n",
  992. +                  tmp->i_ino, tmp->i_count, inode->i_count);
  993. +        tmp->i_count++;
  994. +        return tmp;
  995. +    }
  996. +
  997. +    /* Find a new superinode, avoiding collisions with old
  998. +           obsolete superinodes by a quadratic hash. */
  999. +    new_ino = inode->i_ino;
  1000. +    for ( ; (tmp = iget(sb, new_ino)) && tmp->i_count > 1 &&
  1001. +            inode_is_obsolete(tmp); ) {
  1002. +        iput(tmp);
  1003. +        new_ino += incr;
  1004. +        new_ino &= 0xffffff;
  1005. +        incr <<= 1; incr++;
  1006. +    }
  1007. +    
  1008. +    tmp->u.supermount_i.i_subino = inode->i_ino;
  1009. +    /* If we found a previously obsolete inode which is now no
  1010. +           longer used, we can safely remove the obsolesence flag. */
  1011. +    if (inode_is_obsolete(tmp)) {
  1012. +        tmp->u.supermount_i.i_sb_version = 
  1013. +            tmp->i_sb->u.supermount_sb.s_version;
  1014. +    }
  1015. +    
  1016. +    /* We have now done iget() on superi and subi.  Doing the
  1017. +           attachment may incur another iget() on the subinode. */
  1018. +    if (!tmp->u.supermount_i.i_hidden) {
  1019. +        read_hidden_inode(tmp);
  1020. +        iput(inode);
  1021. +    }
  1022. +    return tmp;
  1023. +}
  1024. +
  1025. +/* Supermount open/close inode.  These functions maintain the
  1026. +   superblock reference counts of active inodes; the subfs is
  1027. +   suspended when that count reaches zero.
  1028. +
  1029. +   Files are opened on any significant reference, and are not closed
  1030. +   until they become fully dereferenced (during the last iput).
  1031. +   Directories, on the other hand, are always closed unless they are
  1032. +   active and opened; a directory referenced as CWD is not open.
  1033. +
  1034. +   The difference is in the way the application gets given inodes.
  1035. +   For dirs and symlinks, it will be given the superinode to deal
  1036. +   with; for other file types, we return the subinode. */
  1037. +
  1038. +
  1039. +void supermount_iopen(struct inode * inode)
  1040. +{
  1041. +    supermount_debug ("inode %ld, count %d\n", 
  1042. +              inode->i_ino, inode->i_count);
  1043. +    if (inode->i_sb->u.supermount_sb.s_state == SUPERMOUNT_UNMOUNTED)
  1044. +        supermount_panic (inode->i_sb, "supermount_iopen", 
  1045. +                  "opening inode on unmounted subfs");
  1046. +    if (!inode->u.supermount_i.i_counted) {
  1047. +        supermount_debug("Opened inode %ld\n", inode->i_ino);
  1048. +        inode->u.supermount_i.i_counted = 1;
  1049. +        if (!subfs_is_active(inode->i_sb)) {
  1050. +            supermount_debug ("going online.\n");
  1051. +            inode->i_sb->u.supermount_sb.s_state = 
  1052. +                SUPERMOUNT_ONLINE;
  1053. +        }
  1054. +        inode->i_sb->u.supermount_sb.s_opencount++;
  1055. +    }
  1056. +}
  1057. +
  1058. +void supermount_iclose(struct inode * inode)
  1059. +{
  1060. +    supermount_debug ("inode %ld, count %d\n", 
  1061. +              inode->i_ino, inode->i_count);
  1062. +    if (inode->u.supermount_i.i_counted) {
  1063. +        supermount_debug("Closed inode %ld\n", inode->i_ino);
  1064. +        inode->u.supermount_i.i_counted = 0;
  1065. +        inode->i_sb->u.supermount_sb.s_opencount--;
  1066. +        if (!subfs_is_active(inode->i_sb))
  1067. +            supermount_go_inactive(inode->i_sb);
  1068. +    }
  1069. +}
  1070. +
  1071. +void supermount_go_inactive(struct super_block *sb)
  1072. +{
  1073. +    supermount_debug("Checking state\n");
  1074. +    if (!subfs_is_active(sb)) {
  1075. +        supermount_debug("going offline.\n");
  1076. +        sb->u.supermount_sb.s_state = 
  1077. +            SUPERMOUNT_SUSPENDED;
  1078. +        if (subfs_is_dirty(sb)) {
  1079. +            mark_subfs_clean(sb);
  1080. +            fsync_dev(sb->u.supermount_sb.s_subfs->s_dev);
  1081. +        }
  1082. +    }
  1083. +}
  1084. +
  1085. +static void read_hidden_inode (struct inode * inode)
  1086. +{
  1087. +    struct super_block * sb;
  1088. +    struct inode * tmp;
  1089. +
  1090. +    supermount_debug("inode = %ld\n", inode->i_ino);
  1091. +    supermount_media_check(inode->i_sb);
  1092. +
  1093. +    if (inode->i_sb->u.supermount_sb.s_state ==
  1094. +        SUPERMOUNT_UNMOUNTED) {
  1095. +        supermount_panic (inode->i_sb, "read_hidden_inode",
  1096. +                  "Trying to read inode on unmounted media");
  1097. +    }
  1098. +    sb=inode->i_sb->u.supermount_sb.s_subfs;
  1099. +    /* The root inode is a bit special.  For that one, the
  1100. +           subinode is the root of the subfs, and we can't guarantee
  1101. +           its inode number in advance. */
  1102. +    if (inode->i_ino == SUPERMOUNT_ROOT_INO) {
  1103. +        tmp = sb->s_mounted;
  1104. +        tmp->i_count++;
  1105. +    } else {
  1106. +        if (!inode->u.supermount_i.i_subino)
  1107. +            inode->u.supermount_i.i_subino = inode->i_ino;
  1108. +        tmp = iget(sb, inode->u.supermount_i.i_subino);
  1109. +    }
  1110. +    if (!tmp)
  1111. +        return;
  1112. +
  1113. +    /* If the inode is already linked to its superinode, don't do
  1114. +           any further processing.  Also, don't bother trying to
  1115. +           attach to the superinode if we are reading from an obsolete
  1116. +           superinode. */
  1117. +    if (tmp->i_shadow || inode_is_obsolete(inode))
  1118. +        return;
  1119. +    tmp->i_shadow = inode;
  1120. +    inode->u.supermount_i.i_hidden = tmp;
  1121. +    inode->i_count++;
  1122. +    supermount_iopen(inode);
  1123. +
  1124. +    inode->i_mode = tmp->i_mode;
  1125. +    inode->i_uid = tmp->i_uid;
  1126. +    inode->i_gid = tmp->i_gid;
  1127. +    inode->i_nlink = tmp->i_nlink;
  1128. +    inode->i_size = tmp->i_size;
  1129. +    inode->i_atime = tmp->i_atime;
  1130. +    inode->i_ctime = tmp->i_ctime;
  1131. +    inode->i_mtime = tmp->i_mtime;
  1132. +    inode->i_blksize = tmp->i_blksize;
  1133. +    inode->i_blocks = tmp->i_blocks;
  1134. +    inode->i_rdev = tmp->i_rdev;
  1135. +    inode->i_version = ++event;
  1136. +
  1137. +    if (S_ISDIR(inode->i_mode))
  1138. +        inode->i_op = &supermount_dir_iops;
  1139. +    else
  1140. +        inode->i_op = NULL;
  1141. +}
  1142. +
  1143. +void supermount_read_inode (struct inode * inode)
  1144. +{
  1145. +    supermount_debug ("inode = %ld\n", inode->i_ino);
  1146. +    
  1147. +    inode->i_shadow_op = &supermount_shadow_iops;
  1148. +    inode->u.supermount_i.i_sb_version = 
  1149. +        inode->i_sb->u.supermount_sb.s_version;
  1150. +    
  1151. +    switch (inode->i_ino) {
  1152. +    case SUPERMOUNT_ROOT_INO:
  1153. +        if (inode->i_sb->u.supermount_sb.s_state !=
  1154. +            SUPERMOUNT_UNMOUNTED) {
  1155. +            supermount_panic (inode->i_sb, "supermount_read_inode",
  1156. +                      "Help - trying to read root while "
  1157. +                      "already mounted!");
  1158. +        }
  1159. +        /* Fall through */
  1160. +    case SUPERMOUNT_HIDDEN_INO:
  1161. +        inode->i_mode = inode->i_sb->u.supermount_sb.s_default_mode;
  1162. +        inode->i_uid = 0;
  1163. +        inode->i_gid = 0;
  1164. +        inode->i_nlink = 1;
  1165. +        inode->i_size = 0;
  1166. +        inode->i_atime = CURRENT_TIME;
  1167. +        inode->i_ctime = CURRENT_TIME;
  1168. +        inode->i_mtime = CURRENT_TIME;
  1169. +        inode->i_blksize = inode->i_sb->s_blocksize;
  1170. +        inode->i_blocks = 0;
  1171. +        inode->i_version = ++event;
  1172. +        inode->i_op = (inode->i_ino == SUPERMOUNT_ROOT_INO)
  1173. +            ? &supermount_dir_iops : NULL;
  1174. +        return;
  1175. +    default:
  1176. +        ;
  1177. +    }
  1178. +}
  1179. +
  1180. +void supermount_write_inode (struct inode * inode)
  1181. +{
  1182. +    struct super_block *tmp;
  1183. +    tmp = inode->i_sb->u.supermount_sb.s_subfs;
  1184. +    
  1185. +    if (inode->u.supermount_i.i_hidden &&
  1186. +        tmp && tmp->s_op && tmp->s_op->write_inode)
  1187. +        tmp->s_op->write_inode(inode->u.supermount_i.i_hidden);
  1188. +
  1189. +    mark_subfs_dirty(inode->i_sb);
  1190. +}
  1191. +
  1192. +int supermount_permission (struct inode * inode, int mask)
  1193. +{
  1194. +    unsigned short mode;
  1195. +    struct inode *subi;
  1196. +
  1197. +    supermount_debug("inode %ld, mask 0%o\n", inode->i_ino, mask);
  1198. +
  1199. +    subi = subiget(inode);
  1200. +    if (!subi)
  1201. +        return -EIO;
  1202. +    if (subi->i_op && subi->i_op->permission) {
  1203. +        int rc = subi->i_op->permission(subi, mask);
  1204. +        iput(subi);
  1205. +        return rc;
  1206. +    }
  1207. +    
  1208. +    mode = inode->i_mode;
  1209. +    /*
  1210. +     * Special case, access is always granted for root
  1211. +     */
  1212. +    if (fsuser()) {
  1213. +        iput(subi);
  1214. +        return 0;
  1215. +    } else if (current->fsuid == inode->i_uid)
  1216. +        mode >>= 6;
  1217. +    else if (in_group_p (inode->i_gid))
  1218. +        mode >>= 3;
  1219. +    iput(subi);
  1220. +    if (((mode & mask & S_IRWXO) == mask))
  1221. +        return 0;
  1222. +    else
  1223. +        return -EACCES;
  1224. +}
  1225. Index: linux/fs/supermount/namei.c
  1226. diff -u linux/fs/supermount/namei.c:1.1 linux/fs/supermount/namei.c:1.1.6.1
  1227. --- linux/fs/supermount/namei.c:1.1    Mon Feb 26 17:55:16 1996
  1228. +++ linux/fs/supermount/namei.c    Sat Nov  9 17:27:25 1996
  1229. @@ -0,0 +1,348 @@
  1230. +/*
  1231. + *  linux/fs/supermount/namei.c
  1232. + *
  1233. + *  Copyright (C) 1995
  1234. + *  Stephen Tweedie (sct@dcs.ed.ac.uk)
  1235. + *
  1236. + *  from
  1237. + *
  1238. + *  linux/fs/minix/namei.c
  1239. + *  Copyright (C) 1991, 1992  Linus Torvalds
  1240. + *
  1241. + *  and
  1242. + *
  1243. + *  linux/fs/ext2/namei.c
  1244. + *  Copyright (C) 1992, 1993, 1994, 1995  Remy Card
  1245. + */
  1246. +
  1247. +/* This file handles almost all of the normal filesystem running of
  1248. +   supermount.  We don't have to deal to much with the subfs
  1249. +   interface, since we just pass subinodes out to the application on
  1250. +   demand. */
  1251. +
  1252. +#include <asm/segment.h>
  1253. +#include <linux/errno.h>
  1254. +#include <linux/fs.h>
  1255. +#include <linux/supermount_fs.h>
  1256. +#include <linux/fcntl.h>
  1257. +#include <linux/sched.h>
  1258. +#include <linux/stat.h>
  1259. +#include <linux/string.h>
  1260. +#include <linux/locks.h>
  1261. +
  1262. +/* Attach a superinode to a subinode, and prepare a result for the
  1263. +   upper VFS layers.  We return the superinode for directories, and
  1264. +   the subinode for other file types.
  1265. +   */
  1266. +static void attach_and_prepare(struct super_block *sb,
  1267. +                   struct inode *subi, struct inode **result)
  1268. +{
  1269. +    struct inode *superi;
  1270. +    superi = supermount_attach(sb, subi);
  1271. +    /* We have now done iget() on superi and subi. */
  1272. +    
  1273. +    /* If the subfs inode is a directory or a symlink, then we
  1274. +       need to deal with it ourselves, and only give back the
  1275. +       superinode to the application.  Otherwise, we can just
  1276. +       return the subfs inode. */
  1277. +    if (S_ISDIR(subi->i_mode)) {
  1278. +        superi->i_op = &supermount_dir_iops;
  1279. +        iput(subi);
  1280. +        *result = superi;
  1281. +        return;
  1282. +    } else {
  1283. +        /* Not a directory-related inode, so we return the
  1284. +           subfs inode to the upper layers.  We still need the
  1285. +           supermount inode in that case, though, to maintain
  1286. +           reference counts in the supermount superblock. */
  1287. +
  1288. +        iput(superi);
  1289. +        *result = subi;
  1290. +        return;
  1291. +    }
  1292. +}
  1293. +
  1294. +int supermount_lookup (struct inode * dir, const char * name, int len,
  1295. +               struct inode ** result)
  1296. +{
  1297. +    struct inode *subi, *subdir;
  1298. +    int rc;
  1299. +    
  1300. +    supermount_debug ("inode = %ld, name = %*s\n",
  1301. +              dir->i_ino, len, name);
  1302. +
  1303. +    *result = NULL;
  1304. +    if (!dir)
  1305. +        return -ENOENT;
  1306. +    if (!S_ISDIR(dir->i_mode)) {
  1307. +        iput(dir);
  1308. +        return -ENOENT;
  1309. +    }
  1310. +    if (!(subdir = subiget(dir)))  {
  1311. +        /* This now becomes the *easy* case. :-) */
  1312. +        iput (dir);
  1313. +        return -EIO;
  1314. +    }
  1315. +
  1316. +    rc = subdir->i_op->lookup(subdir, name, len, &subi);
  1317. +    supermount_go_inactive(dir->i_sb);
  1318. +    iput (dir);
  1319. +    if (rc)
  1320. +        return rc;
  1321. +    /* It worked, so now create a shadow supermount inode for the
  1322. +           result... */
  1323. +    attach_and_prepare(dir->i_sb, subi, result);
  1324. +    return 0;
  1325. +}
  1326. +
  1327. +int supermount_create (struct inode * dir,const char * name, int len, int mode,
  1328. +               struct inode ** result)
  1329. +{
  1330. +    struct inode * inode, * subi;
  1331. +    int rc;
  1332. +    
  1333. +    supermount_debug ("inode = %ld, name = %*s, mode = %o\n",
  1334. +              dir->i_ino, len, name, mode);
  1335. +
  1336. +    *result = NULL;
  1337. +    if (!dir)
  1338. +        return -ENOENT;
  1339. +    inode = subiget(dir);
  1340. +    if (!inode) {
  1341. +        iput(dir);
  1342. +        return -ENOENT;
  1343. +    }
  1344. +    if (!inode->i_op || !inode->i_op->create) {
  1345. +        iput(dir);
  1346. +        iput(inode);
  1347. +        return -EPERM;
  1348. +    }
  1349. +    
  1350. +    rc = inode->i_op->create(inode, name, len, mode, &subi);
  1351. +    mark_subfs_dirty(dir->i_sb);
  1352. +    supermount_go_inactive(dir->i_sb);
  1353. +    iput(dir);
  1354. +    if (rc)
  1355. +        return rc;
  1356. +    attach_and_prepare(dir->i_sb, subi, result);
  1357. +    return 0;
  1358. +}
  1359. +
  1360. +int supermount_mknod (struct inode * dir, const char * name, int len, int mode,
  1361. +              int rdev)
  1362. +{
  1363. +    struct inode * inode;
  1364. +    int rc;
  1365. +    
  1366. +    supermount_debug ("inode = %ld, name = %*s, mode = %o\n",
  1367. +              dir->i_ino, len, name, mode);
  1368. +
  1369. +    if (!dir)
  1370. +        return -ENOENT;
  1371. +    inode = subiget(dir);
  1372. +    if (!inode) {
  1373. +        iput(dir);
  1374. +        return -ENOENT;
  1375. +    }
  1376. +    if (!inode->i_op || !inode->i_op->mknod) {
  1377. +        iput(dir);
  1378. +        iput(inode);
  1379. +        return -EPERM;
  1380. +    }
  1381. +    
  1382. +    rc = inode->i_op->mknod(inode, name, len, mode, rdev);
  1383. +    mark_subfs_dirty(dir->i_sb);
  1384. +    supermount_go_inactive(dir->i_sb);
  1385. +    iput(dir);
  1386. +    return rc;
  1387. +}
  1388. +
  1389. +int supermount_mkdir (struct inode * dir, const char * name, int len, int mode)
  1390. +{
  1391. +    struct inode * inode;
  1392. +    int rc;
  1393. +    
  1394. +    supermount_debug ("inode = %ld, name = %*s, mode = %o\n",
  1395. +              dir->i_ino, len, name, mode);
  1396. +
  1397. +    if (!dir)
  1398. +        return -ENOENT;
  1399. +    inode = subiget(dir);
  1400. +    if (!inode) {
  1401. +        iput(dir);
  1402. +        return -ENOENT;
  1403. +    }
  1404. +    if (!inode->i_op || !inode->i_op->mkdir) {
  1405. +        iput(dir);
  1406. +        iput(inode);
  1407. +        return -EPERM;
  1408. +    }
  1409. +    
  1410. +    rc = inode->i_op->mkdir(inode, name, len, mode);
  1411. +    mark_subfs_dirty(dir->i_sb);
  1412. +    supermount_go_inactive(dir->i_sb);
  1413. +    iput(dir);
  1414. +    return rc;
  1415. +}
  1416. +
  1417. +int supermount_rmdir (struct inode * dir, const char * name, int len)
  1418. +{
  1419. +    struct inode * inode;
  1420. +    int rc;
  1421. +    
  1422. +    supermount_debug ("inode = %ld, name = %*s\n",
  1423. +              dir->i_ino, len, name);
  1424. +
  1425. +    if (!dir)
  1426. +        return -ENOENT;
  1427. +    inode = subiget(dir);
  1428. +    if (!inode) {
  1429. +        iput(dir);
  1430. +        return -ENOENT;
  1431. +    }
  1432. +    if (!inode->i_op || !inode->i_op->rmdir) {
  1433. +        iput(dir);
  1434. +        iput(inode);
  1435. +        return -EPERM;
  1436. +    }
  1437. +    
  1438. +    rc = inode->i_op->rmdir(inode, name, len);
  1439. +    mark_subfs_dirty(dir->i_sb);
  1440. +    supermount_go_inactive(dir->i_sb);
  1441. +    iput(dir);
  1442. +    return rc;
  1443. +}
  1444. +
  1445. +int supermount_unlink (struct inode * dir, const char * name, int len)
  1446. +{
  1447. +    struct inode * inode;
  1448. +    int rc;
  1449. +    
  1450. +    supermount_debug ("inode = %ld, name = %*s\n",
  1451. +              dir->i_ino, len, name);
  1452. +
  1453. +    if (!dir)
  1454. +        return -ENOENT;
  1455. +    inode = subiget(dir);
  1456. +    if (!inode) {
  1457. +        iput(dir);
  1458. +        return -ENOENT;
  1459. +    }
  1460. +    if (!inode->i_op || !inode->i_op->unlink) {
  1461. +        iput(dir);
  1462. +        iput(inode);
  1463. +        return -EPERM;
  1464. +    }
  1465. +    
  1466. +    rc = inode->i_op->unlink(inode, name, len);
  1467. +    mark_subfs_dirty(dir->i_sb);
  1468. +    supermount_go_inactive(dir->i_sb);
  1469. +    iput(dir);
  1470. +    return rc;
  1471. +}
  1472. +
  1473. +int supermount_symlink (struct inode * dir, const char * name, int len,
  1474. +            const char * symname)
  1475. +{
  1476. +    struct inode * inode;
  1477. +    int rc;
  1478. +    
  1479. +    supermount_debug ("inode = %ld, name = %*s, link = %s\n",
  1480. +              dir->i_ino, len, name, symname);
  1481. +
  1482. +    if (!dir)
  1483. +        return -ENOENT;
  1484. +    inode = subiget(dir);
  1485. +    if (!inode) {
  1486. +        iput(dir);
  1487. +        return -ENOENT;
  1488. +    }
  1489. +    if (!inode->i_op || !inode->i_op->symlink) {
  1490. +        iput(dir);
  1491. +        iput(inode);
  1492. +        return -EPERM;
  1493. +    }
  1494. +    
  1495. +    rc = inode->i_op->symlink(inode, name, len, symname);
  1496. +    mark_subfs_dirty(dir->i_sb);
  1497. +    supermount_go_inactive(dir->i_sb);
  1498. +    iput(dir);
  1499. +    return rc;
  1500. +}
  1501. +
  1502. +/* This probably won't work because higher levels will complain about
  1503. +   cross-device links. */
  1504. +int supermount_link (struct inode * oldinode, struct inode * dir,
  1505. +             const char * name, int len)
  1506. +{
  1507. +    struct inode * inode;
  1508. +    int rc;
  1509. +    
  1510. +    supermount_debug ("inode = %ld, name = %*s, link to inode %ld\n",
  1511. +              dir->i_ino, len, name, oldinode->i_ino);
  1512. +
  1513. +    if (!dir)
  1514. +        return -ENOENT;
  1515. +    inode = subiget(dir);
  1516. +    if (!inode) {
  1517. +        iput(dir);
  1518. +        return -ENOENT;
  1519. +    }
  1520. +    if (!inode->i_op || !inode->i_op->link) {
  1521. +        iput(dir);
  1522. +        iput(inode);
  1523. +        return -EPERM;
  1524. +    }
  1525. +    
  1526. +    rc = inode->i_op->link(oldinode, inode, name, len);
  1527. +    mark_subfs_dirty(dir->i_sb);
  1528. +    supermount_go_inactive(dir->i_sb);
  1529. +    iput(dir);
  1530. +    return rc;
  1531. +}
  1532. +
  1533. +int supermount_rename (struct inode * old_dir, const char * old_name, 
  1534. +               int old_len,
  1535. +               struct inode * new_dir, const char * new_name, 
  1536. +               int new_len, int must_be_dir)
  1537. +{
  1538. +    struct inode * old_subi, * new_subi;
  1539. +    int rc;
  1540. +    
  1541. +    supermount_debug ("from inode %ld, %*s to inode %ld, %*s\n",
  1542. +              old_dir->i_ino, old_len, old_name,
  1543. +              new_dir->i_ino, new_len, new_name);
  1544. +
  1545. +    if (!old_dir || !new_dir)
  1546. +        return -ENOENT;
  1547. +    old_subi = subiget(old_dir);
  1548. +    if (!old_subi) {
  1549. +        iput(old_dir);
  1550. +        iput(new_dir);
  1551. +        return -ENOENT;
  1552. +    }
  1553. +    new_subi = subiget(new_dir);
  1554. +    if (!new_subi) {
  1555. +        iput(old_dir);
  1556. +        iput(new_dir);
  1557. +        iput(old_subi);
  1558. +        return -ENOENT;
  1559. +    }
  1560. +
  1561. +    if (!old_subi->i_op || !old_subi->i_op->rename) {
  1562. +        iput(old_dir);
  1563. +        iput(new_dir);
  1564. +        iput(old_subi);
  1565. +        iput(new_subi);
  1566. +        return -EPERM;
  1567. +    }
  1568. +    
  1569. +    rc = old_subi->i_op->rename(old_subi, old_name, old_len,
  1570. +                    new_subi, new_name, new_len, 
  1571. +                    must_be_dir);
  1572. +    mark_subfs_dirty(old_dir->i_sb);
  1573. +    supermount_go_inactive(old_dir->i_sb);
  1574. +    iput(old_dir);
  1575. +    iput(new_dir);
  1576. +    return rc;
  1577. +}
  1578. Index: linux/fs/supermount/super.c
  1579. diff -u linux/fs/supermount/super.c:1.1 linux/fs/supermount/super.c:1.1.6.2
  1580. --- linux/fs/supermount/super.c:1.1    Mon Feb 26 17:55:16 1996
  1581. +++ linux/fs/supermount/super.c    Sat Nov  9 19:57:42 1996
  1582. @@ -0,0 +1,431 @@
  1583. +/*
  1584. + *  linux/fs/supermount/super.c
  1585. + *
  1586. + *  Copyright (C) 1995
  1587. + *  Stephen Tweedie (sct@dcs.ed.ac.uk)
  1588. + *
  1589. + *  from
  1590. + *
  1591. + *  linux/fs/minix/inode.c
  1592. + *  Copyright (C) 1991, 1992  Linus Torvalds
  1593. + *
  1594. + *  and
  1595. + *
  1596. + *  linux/fs/ext2/super.c
  1597. + *  Copyright (C) 1992, 1993, 1994, 1995  Remy Card
  1598. + */
  1599. +
  1600. +#include <stdarg.h>
  1601. +
  1602. +#include <asm/segment.h>
  1603. +#include <asm/system.h>
  1604. +
  1605. +#include <linux/errno.h>
  1606. +#include <linux/fs.h>
  1607. +#include <linux/supermount_fs.h>
  1608. +#include <linux/malloc.h>
  1609. +#include <linux/sched.h>
  1610. +#include <linux/stat.h>
  1611. +#include <linux/string.h>
  1612. +#include <linux/locks.h>
  1613. +#include <linux/major.h>
  1614. +
  1615. +/* From fs/super.c */
  1616. +extern int do_umount(kdev_t);
  1617. +
  1618. +#ifdef SUPERMOUNT_DEBUG
  1619. +char supermount_debug_enable = 0;
  1620. +#endif
  1621. +
  1622. +static struct super_operations supermount_sops = { 
  1623. +    supermount_read_inode,
  1624. +    NULL,
  1625. +    supermount_write_inode,
  1626. +    NULL,                /* put_inode */
  1627. +    supermount_put_super,
  1628. +    supermount_write_super,
  1629. +    supermount_statfs,
  1630. +    NULL,                 /* supermount_remount */
  1631. +};
  1632. +
  1633. +static char error_buf[1024];
  1634. +
  1635. +/* Mount and mount the hidden fs */
  1636. +static void umount_subfs(struct super_block *);
  1637. +
  1638. +void supermount_error (struct super_block * sb, const char * function,
  1639. +               const char * fmt, ...)
  1640. +{
  1641. +    va_list args;
  1642. +
  1643. +    va_start (args, fmt);
  1644. +    vsprintf (error_buf, fmt, args);
  1645. +    va_end (args);
  1646. +    printk (KERN_CRIT "SUPERMOUNT error (device %d/%d): %s: %s\n",
  1647. +        MAJOR(sb->s_dev), MINOR(sb->s_dev), function, error_buf);
  1648. +    /* @@ Do we want to do any special error handling here? */
  1649. +}
  1650. +
  1651. +NORET_TYPE void supermount_panic (struct super_block * sb,
  1652. +                  const char * function,
  1653. +                  const char * fmt, ...)
  1654. +{
  1655. +    va_list args;
  1656. +
  1657. +    va_start (args, fmt);
  1658. +    vsprintf (error_buf, fmt, args);
  1659. +    va_end (args);
  1660. +    panic ("SUPERMOUNT panic (device %d/%d): %s: %s\n",
  1661. +           MAJOR(sb->s_dev), MINOR(sb->s_dev), function, error_buf);
  1662. +}
  1663. +
  1664. +void supermount_warning (struct super_block * sb, const char * function,
  1665. +           const char * fmt, ...)
  1666. +{
  1667. +    va_list args;
  1668. +
  1669. +    va_start (args, fmt);
  1670. +    vsprintf (error_buf, fmt, args);
  1671. +    va_end (args);
  1672. +    printk (KERN_WARNING "SUPERMOUNT-fs warning (device %d/%d): %s: %s\n",
  1673. +        MAJOR(sb->s_dev), MINOR(sb->s_dev), function, error_buf);
  1674. +}
  1675. +
  1676. +/* Release the superblock and any resources it has reserved */
  1677. +void supermount_put_super (struct super_block * sb)
  1678. +{
  1679. +    lock_super (sb);
  1680. +    if (sb->u.supermount_sb.s_state != SUPERMOUNT_UNMOUNTED)
  1681. +        umount_subfs (sb);
  1682. +    sb->s_dev = 0;
  1683. +    unlock_super (sb);
  1684. +}
  1685. +
  1686. +
  1687. +static int copy_option(const char **option, const char *val)
  1688. +{
  1689. +    char *tmp;
  1690. +    supermount_debug ("assigning value \"%s\"\n", val);
  1691. +    if (!val || !*val)
  1692. +        return -EINVAL;
  1693. +    tmp = (char *) kmalloc(1 + strlen(val), GFP_KERNEL);
  1694. +    if (!tmp)
  1695. +        return -ENOMEM;
  1696. +    strcpy(tmp, val);
  1697. +    *option = tmp;
  1698. +    return 0;
  1699. +}
  1700. +
  1701. +/*
  1702. + * This function has been shamelessly adapted from the msdos fs
  1703. + */
  1704. +static int parse_options (char * options, struct super_block *sb)
  1705. +{
  1706. +    char * this_char;
  1707. +    char * value;
  1708. +    int rc;
  1709. +    
  1710. +    if (!options)
  1711. +        return 0;
  1712. +    while ((this_char = options)) {
  1713. +        if (!strncmp(this_char, "--,", 3))
  1714. +            this_char += 2;
  1715. +        if (*this_char == ',') {
  1716. +            /* An empty option, or the option "--",
  1717. +               introduces options to be passed through to
  1718. +               the subfs */
  1719. +            supermount_debug ("assigning remainder\n");
  1720. +            return copy_option(&sb->u.supermount_sb.s_data,
  1721. +                       ++this_char);
  1722. +        }
  1723. +        if ((options = strchr (this_char, ',')))
  1724. +            *options++ = 0;
  1725. +        
  1726. +        if ((value = strchr (this_char, '=')) != NULL)
  1727. +            *value++ = 0;
  1728. +
  1729. +        supermount_debug ("parsing option \"%s\"\n", this_char);
  1730. +        if (!strcmp (this_char, "fs")) {
  1731. +            rc = copy_option(&sb->u.supermount_sb.s_type, value);
  1732. +            if (rc) return rc;
  1733. +        } else if (!strcmp (this_char, "dev")) {
  1734. +            rc = copy_option(&sb->u.supermount_sb.s_devname, 
  1735. +                     value);
  1736. +            if (rc) return rc;
  1737. +        } else if (!strcmp (this_char, "debug")) {
  1738. +            supermount_debug_enable = 1;
  1739. +        } else {
  1740. +            printk ("supermount: "
  1741. +                "Unrecognized mount option %s\n", this_char);
  1742. +            return -EINVAL;
  1743. +        }
  1744. +    }
  1745. +    return 0;
  1746. +}
  1747. +
  1748. +/* read_super: the main mount() entry point into the VFS layer. */
  1749. +struct super_block * supermount_read_super (struct super_block * sb, 
  1750. +                        void * data,
  1751. +                        int silent)
  1752. +{
  1753. +    sb->s_blocksize = 1024;
  1754. +    sb->s_blocksize_bits = 10;
  1755. +    sb->s_magic = SUPERMOUNT_SUPER_MAGIC;
  1756. +    sb->s_op = &supermount_sops;
  1757. +    unlock_super(sb);
  1758. +    sb->u.supermount_sb.s_state = SUPERMOUNT_UNMOUNTED;
  1759. +    sb->u.supermount_sb.s_default_mode = 0777 | S_IFDIR;
  1760. +    sb->u.supermount_sb.s_mflags = sb->s_flags & (MS_REMOUNT - 1);
  1761. +    sb->u.supermount_sb.s_data = NULL;
  1762. +    sb->u.supermount_sb.s_undermount = NULL;
  1763. +    sb->u.supermount_sb.s_subfs = NULL;
  1764. +    sb->u.supermount_sb.s_opencount = 0;
  1765. +    sb->u.supermount_sb.s_dirty = 0;
  1766. +    sb->u.supermount_sb.s_type = NULL;
  1767. +    sb->u.supermount_sb.s_devname = NULL;
  1768. +
  1769. +    if (parse_options ((char *) data, sb)) {
  1770. +        sb->s_dev = 0;
  1771. +        return NULL;
  1772. +    }
  1773. +    if (!sb->u.supermount_sb.s_type)
  1774. +        copy_option(&sb->u.supermount_sb.s_type, "msdos");
  1775. +    if (!sb->u.supermount_sb.s_devname)
  1776. +        copy_option(&sb->u.supermount_sb.s_devname, "/dev/fd0");
  1777. +
  1778. +    sb->s_flags = sb->u.supermount_sb.s_mflags;
  1779. +    if (!(sb->s_mounted = iget(sb, SUPERMOUNT_ROOT_INO))) {
  1780. +        sb->s_dev = 0;
  1781. +        supermount_error (sb, "supermount_read_super",
  1782. +                  "get root inode failed\n");
  1783. +        return NULL;
  1784. +    }
  1785. +    return sb;
  1786. +}
  1787. +
  1788. +void supermount_write_super (struct super_block * sb)
  1789. +{
  1790. +    supermount_media_check(sb);
  1791. +    if (sb->u.supermount_sb.s_state != SUPERMOUNT_UNMOUNTED) {
  1792. +        struct super_block *tmp = sb->u.supermount_sb.s_subfs;
  1793. +        if (tmp && tmp->s_op && tmp->s_op->write_super)
  1794. +            tmp->s_op->write_super(tmp);
  1795. +    }
  1796. +    sb->s_dirt = 0;
  1797. +}
  1798. +
  1799. +#if 0
  1800. +int supermount_remount (struct super_block * sb, int * flags, char * data)
  1801. +{
  1802. +}
  1803. +#endif /* 0 */
  1804. +
  1805. +void supermount_statfs (struct super_block * sb, struct statfs * buf, 
  1806. +            int bufsize)
  1807. +{
  1808. +    unsigned short fs;
  1809. +    struct statfs tmp;
  1810. +    supermount_media_check(sb);
  1811. +
  1812. +    if (sb->u.supermount_sb.s_state != SUPERMOUNT_UNMOUNTED) {
  1813. +        struct super_block * tmpsb = 
  1814. +            sb->u.supermount_sb.s_undermount->i_mount->i_sb;
  1815. +        fs = get_fs();
  1816. +        set_fs(KERNEL_DS);
  1817. +        if (tmpsb->s_op && tmpsb->s_op->statfs)
  1818. +            tmpsb->s_op->statfs(tmpsb, &tmp, sizeof(tmp));
  1819. +        set_fs(fs);
  1820. +    } else {
  1821. +        tmp.f_bsize = sb->s_blocksize;
  1822. +        tmp.f_blocks = 0;
  1823. +        tmp.f_bfree = 0;
  1824. +        tmp.f_bavail = 0;
  1825. +        tmp.f_files = 0;
  1826. +        tmp.f_ffree = 0;
  1827. +        tmp.f_namelen = 0;
  1828. +    }
  1829. +    tmp.f_type = SUPERMOUNT_SUPER_MAGIC;
  1830. +    memcpy_tofs(buf, &tmp, bufsize);
  1831. +}
  1832. +
  1833. +/* Check for media change, but without invalidating buffers and inodes */
  1834. +static int just_check_disk_change(dev_t dev)
  1835. +{
  1836. +    if (!query_disk_change(dev))
  1837. +        return 0;
  1838. +    supermount_debug("Disk change detected on device %d/%d\n",
  1839. +             MAJOR(dev), MINOR(dev));
  1840. +    return 1;
  1841. +}
  1842. +
  1843. +static void umount_subfs(struct super_block *sb)
  1844. +{
  1845. +    int retval;
  1846. +    struct inode *inode, *subi;
  1847. +    
  1848. +    supermount_debug("Trying to unmount device %s.\n",
  1849. +             sb->u.supermount_sb.s_devname);
  1850. +    
  1851. +    /* Detach the subfs from the supermount root inode */
  1852. +    inode = sb->s_mounted;
  1853. +    /* Inode may not be set if we are currently unmounting the superfs */
  1854. +    if (inode) {
  1855. +        subi = inode->u.supermount_i.i_hidden;
  1856. +        if (subi) {
  1857. +            subi->i_shadow = 0;
  1858. +            inode->u.supermount_i.i_hidden = 0;
  1859. +            iput(inode);
  1860. +        }
  1861. +    }
  1862. +        
  1863. +    if (sb->u.supermount_sb.s_subfs->s_mounted->i_count != 1)
  1864. +        supermount_panic (sb, "umount_subfs",
  1865. +                  "subfs root i_count = %d, should be 1\n",
  1866. +                  sb->u.supermount_sb.s_subfs->s_mounted->i_count);
  1867. +    if (sb->u.supermount_sb.s_undermount->i_count != 1)
  1868. +        supermount_panic (sb, "umount_subfs",
  1869. +                  "undermount i_count = %d, should be 1\n",
  1870. +                  sb->u.supermount_sb.s_subfs->s_mounted->i_count);
  1871. +
  1872. +    sb->u.supermount_sb.s_subfs->s_mounted->i_count++;
  1873. +    sb->u.supermount_sb.s_state = SUPERMOUNT_UNMOUNTED;
  1874. +    retval = do_umounti(sb->u.supermount_sb.s_subfs->s_mounted);
  1875. +    if (retval)
  1876. +        supermount_panic (sb, "umount_subfs",
  1877. +                  "Help - can't umount subfs!!!");
  1878. +    supermount_debug("subfs is unmounted.\n");
  1879. +    sb->u.supermount_sb.s_undermount = 0;
  1880. +    sb->u.supermount_sb.s_version = ++event;
  1881. +    sb->u.supermount_sb.s_subfs = 0;
  1882. +    sb->s_flags = sb->u.supermount_sb.s_mflags;
  1883. +    if (inode)
  1884. +        inode->i_mode = sb->u.supermount_sb.s_default_mode;
  1885. +}
  1886. +
  1887. +/* Return 0 (OK) if medium is valid. */
  1888. +int supermount_media_check(struct super_block * sb) 
  1889. +{
  1890. +    int retval;
  1891. +    unsigned short fs;
  1892. +
  1893. +    /* If there are still files open, we never bother checking the
  1894. +           medium. */
  1895. +    if (sb->u.supermount_sb.s_subfs && 
  1896. +        subfs_is_active(sb)) {
  1897. +        supermount_debug ("subfs is active.\n");
  1898. +        return 0;
  1899. +    }
  1900. +
  1901. +    supermount_debug ("starting (%sactive now)\n",
  1902. +              (sb->u.supermount_sb.s_subfs &&
  1903. +               subfs_is_active(sb)) ?
  1904. +              "" : "not ");
  1905. +    
  1906. +    lock_super(sb);
  1907. +
  1908. +    /* Are we checking for mount or unmount/remount? */
  1909. +    if (sb->u.supermount_sb.s_state != SUPERMOUNT_UNMOUNTED) {
  1910. +        /* Already mounted --- check for disk change or
  1911. +           disk not present */
  1912. +        int dev = sb->u.supermount_sb.s_subfs->s_dev;
  1913. +        if (!just_check_disk_change(dev)) {
  1914. +            unlock_super(sb);
  1915. +            return 0;
  1916. +        }
  1917. +        
  1918. +        /* We have a disk change!  Unmount the subfs */
  1919. +        supermount_debug ("trying to unmount\n");
  1920. +        umount_subfs(sb);
  1921. +        /* The call to just_check_disk_change may clear the media-
  1922. +           changed flag on the device, so we need to force a media
  1923. +           invalidation.  We don't want to do this before unmounting
  1924. +           the subfs, naturally! */
  1925. +        invalidate_media(dev);
  1926. +        /* Now we are unmounted; fall through to the next check. */
  1927. +    }
  1928. +    
  1929. +    if (sb->u.supermount_sb.s_state != SUPERMOUNT_UNMOUNTED) {
  1930. +        unlock_super(sb);
  1931. +        return 0;
  1932. +    }
  1933. +    
  1934. +    /* OK, we're unmounted now --- can we remount?  Please? */
  1935. +    if (!sb->u.supermount_sb.s_undermount) {
  1936. +        sb->u.supermount_sb.s_undermount =
  1937. +            iget(sb, SUPERMOUNT_HIDDEN_INO);
  1938. +        if (!sb->u.supermount_sb.s_undermount)
  1939. +            supermount_panic (sb, "supermount_media_check",
  1940. +                      "Can't get root hidden inode!");
  1941. +        sb->u.supermount_sb.s_undermount->i_flags |= S_UNBOUND;
  1942. +    }
  1943. +
  1944. +    sb->u.supermount_sb.s_version = ++event;
  1945. +    sb->s_mounted->u.supermount_i.i_sb_version = event;
  1946. +    supermount_debug ("trying to mount\n");
  1947. +    supermount_debug ("fs=%s, dev=%s, data=%s, flags=%08lx\n",
  1948. +              sb->u.supermount_sb.s_type,
  1949. +              sb->u.supermount_sb.s_devname,
  1950. +              sb->u.supermount_sb.s_data,
  1951. +              sb->s_flags);
  1952. +    fs = get_fs();
  1953. +    set_fs(KERNEL_DS);
  1954. +    sb->s_flags = sb->u.supermount_sb.s_mflags,
  1955. +        retval = do_mounti(sb->u.supermount_sb.s_undermount,
  1956. +                   "<supermount>",
  1957. +                   sb->u.supermount_sb.s_devname,
  1958. +                   sb->u.supermount_sb.s_type,
  1959. +                   sb->s_flags | MS_MGC_VAL,
  1960. +                   sb->u.supermount_sb.s_data);
  1961. +    if (retval == -EROFS && !(sb->u.supermount_sb.s_mflags & MS_RDONLY)) {
  1962. +        /* OK, that failed, so try it readonly */
  1963. +        sb->s_flags |= MS_RDONLY;
  1964. +        retval = do_mounti(sb->u.supermount_sb.s_undermount,
  1965. +                   "<supermount>",
  1966. +                   sb->u.supermount_sb.s_devname,
  1967. +                   sb->u.supermount_sb.s_type,
  1968. +                   sb->s_flags | MS_MGC_VAL,
  1969. +                   sb->u.supermount_sb.s_data);
  1970. +    }
  1971. +    set_fs(fs);
  1972. +    
  1973. +    unlock_super(sb);
  1974. +    if (retval) {
  1975. +        sb->s_flags = sb->u.supermount_sb.s_mflags;
  1976. +        iput(sb->u.supermount_sb.s_undermount);
  1977. +        sb->u.supermount_sb.s_undermount = 0;
  1978. +        supermount_debug ("Mount failed, errno %d\n", -retval);
  1979. +        return 1;
  1980. +    }
  1981. +    /* Hey --- success!!! */
  1982. +    sb->u.supermount_sb.s_subfs = sb->u.supermount_sb.s_undermount
  1983. +        ->i_mount->i_sb;
  1984. +    if (!sb->u.supermount_sb.s_subfs->s_mounted)
  1985. +        supermount_panic (sb, "supermount_media_check", 
  1986. +                  "Mounted subfs has no root inode!");
  1987. +    sb->u.supermount_sb.s_state = SUPERMOUNT_SUSPENDED;
  1988. +    supermount_debug ("Mount succeeded!\n");
  1989. +    /* For counting open inodes on the subfs, we rely on the fact
  1990. +           that the root inode is always exactly one count.  So make
  1991. +           sure we guarantee it is always open! */
  1992. +    supermount_iopen(sb->s_mounted);
  1993. +    sb->s_mounted->i_flags |= S_UNBOUND;
  1994. +    return 0;
  1995. +}
  1996. +
  1997. +/* Check whether an inode still belongs to valid medium. */
  1998. +int supermount_check_inode(struct inode * inode)
  1999. +{
  2000. +    supermount_debug ("inode = %ld\n", inode->i_ino);
  2001. +    
  2002. +    if (supermount_media_check(inode->i_sb))
  2003. +        return 1;
  2004. +    if (inode_is_obsolete(inode)) {
  2005. +        /* What happens if we remount an old disk, and get
  2006. +                   back the same superinode number?  subiget() will
  2007. +                   handle it through the i_subino field, and
  2008. +                   supermount_attach will avoid reusing the old
  2009. +                   inode. */
  2010. +        return 1;
  2011. +    }
  2012. +    return 0;
  2013. +}
  2014. Index: linux/include/linux/fs.h
  2015. diff -u linux/include/linux/fs.h:1.12 linux/include/linux/fs.h:1.12.2.1
  2016. --- linux/include/linux/fs.h:1.12    Wed Nov  6 23:17:37 1996
  2017. +++ linux/include/linux/fs.h    Sat Nov  9 17:26:30 1996
  2018. @@ -74,6 +74,10 @@
  2019.  #define S_WRITE        128    /* Write on file/directory/symlink */
  2020.  #define S_APPEND    256    /* Append-only file */
  2021.  #define S_IMMUTABLE    512    /* Immutable file */
  2022. +#define S_UNBOUND    1024    /* inode is not bound to user space,
  2023. +                   and so the filesystem may be
  2024. +                   unmounted even if this inode is in
  2025. +                   use. */
  2026.  
  2027.  /*
  2028.   * Flags that can be altered by MS_REMOUNT
  2029. @@ -103,6 +107,7 @@
  2030.  #define IS_WRITABLE(inode) ((inode)->i_flags & S_WRITE)
  2031.  #define IS_APPEND(inode) ((inode)->i_flags & S_APPEND)
  2032.  #define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE)
  2033. +#define IS_UNBOUND(inode) ((inode)->i_flags & S_UNBOUND)
  2034.  
  2035.  /* the read-only stuff doesn't really belong here, but any other place is
  2036.     probably as bad and I don't want to create yet another include file. */
  2037. @@ -216,6 +221,7 @@
  2038.  }
  2039.  
  2040.  #include <linux/pipe_fs_i.h>
  2041. +#include <linux/supermount_fs_i.h>
  2042.  #include <linux/minix_fs_i.h>
  2043.  #include <linux/ext_fs_i.h>
  2044.  #include <linux/ext2_fs_i.h>
  2045. @@ -284,6 +290,8 @@
  2046.      unsigned long    i_nrpages;
  2047.      struct semaphore i_sem;
  2048.      struct inode_operations *i_op;
  2049. +    struct inode * i_shadow;
  2050. +    struct inode_shadow_operations * i_shadow_op;
  2051.      struct super_block *i_sb;
  2052.      struct wait_queue *i_wait;
  2053.      struct file_lock *i_flock;
  2054. @@ -305,6 +313,7 @@
  2055.      unsigned short i_writecount;
  2056.      union {
  2057.          struct pipe_inode_info pipe_i;
  2058. +        struct supermount_inode_info supermount_i;
  2059.          struct minix_inode_info minix_i;
  2060.          struct ext_inode_info ext_i;
  2061.          struct ext2_inode_info ext2_i;
  2062. @@ -402,6 +411,7 @@
  2063.  
  2064.  extern int fasync_helper(struct inode *, struct file *, int, struct fasync_struct **);
  2065.  
  2066. +#include <linux/supermount_fs_sb.h>
  2067.  #include <linux/minix_fs_sb.h>
  2068.  #include <linux/ext_fs_sb.h>
  2069.  #include <linux/ext2_fs_sb.h>
  2070. @@ -431,6 +441,7 @@
  2071.      struct inode * s_mounted;
  2072.      struct wait_queue * s_wait;
  2073.      union {
  2074. +        struct supermount_sb_info supermount_sb;
  2075.          struct minix_sb_info minix_sb;
  2076.          struct ext_sb_info ext_sb;
  2077.          struct ext2_sb_info ext2_sb;
  2078. @@ -491,6 +502,12 @@
  2079.      int (*smap) (struct inode *,int);
  2080.  };
  2081.  
  2082. +struct inode_shadow_operations {
  2083. +    void (*open) (struct inode *, int);
  2084. +    void (*write) (struct inode *);
  2085. +    void (*release) (struct inode *);
  2086. +};
  2087. +
  2088.  struct super_operations {
  2089.      void (*read_inode) (struct inode *);
  2090.      int (*notify_change) (struct inode *, struct iattr *);
  2091. @@ -600,9 +617,11 @@
  2092.  }
  2093.  
  2094.  extern int check_disk_change(kdev_t dev);
  2095. +extern int query_disk_change(kdev_t dev);
  2096.  extern void invalidate_inodes(kdev_t dev);
  2097.  extern void invalidate_inode_pages(struct inode *);
  2098.  extern void invalidate_buffers(kdev_t dev);
  2099. +extern void invalidate_media(kdev_t dev);
  2100.  extern int floppy_is_wp(int minor);
  2101.  extern void sync_inodes(kdev_t dev);
  2102.  extern void sync_dev(kdev_t dev);
  2103. @@ -663,6 +682,9 @@
  2104.  
  2105.  extern void show_buffers(void);
  2106.  extern void mount_root(void);
  2107. +extern int do_mounti(struct inode *_inode, const char *, const char *, 
  2108. +             const char *, unsigned long, const void *);
  2109. +extern int do_umounti(struct inode *);
  2110.  
  2111.  #ifdef CONFIG_BLK_DEV_INITRD
  2112.  extern kdev_t real_root_dev;
  2113. Index: linux/include/linux/supermount_fs.h
  2114. diff -u linux/include/linux/supermount_fs.h:1.1 linux/include/linux/supermount_fs.h:1.1.4.1
  2115. --- linux/include/linux/supermount_fs.h:1.1    Mon Feb 26 17:55:21 1996
  2116. +++ linux/include/linux/supermount_fs.h    Sat Nov  9 17:27:49 1996
  2117. @@ -0,0 +1,165 @@
  2118. +/*
  2119. + *  linux/include/linux/supermount_fs.h
  2120. + *
  2121. + *  Defines and strutures for the dynamic remounting of removable media
  2122. + *
  2123. + *  Copyright (C) 1995
  2124. + *  Stephen Tweedie (sct@dcs.ed.ac.uk)
  2125. + *
  2126. + *  from
  2127. + *
  2128. + *  linux/include/linux/minix_fs.h
  2129. + *  Copyright (C) 1991, 1992  Linus Torvalds
  2130. + *
  2131. + *  and
  2132. + *
  2133. + *  linux/include/linux/ext2_fs.h
  2134. + *  Copyright (C) 1992, 1993, 1994, 1995  Remy Card
  2135. + */
  2136. +
  2137. +#ifndef _LINUX_SUPERMOUNT_FS_H
  2138. +#define _LINUX_SUPERMOUNT_FS_H
  2139. +
  2140. +#include <linux/types.h>
  2141. +
  2142. +#define SUPERMOUNT_DEBUG
  2143. +
  2144. +#define SUPERMOUNT_VERSION        "0.4"
  2145. +
  2146. +/*
  2147. + * Debug code
  2148. + */
  2149. +#ifdef SUPERMOUNT_DEBUG
  2150. + extern char supermount_debug_enable;
  2151. +
  2152. + #define supermount_debug(f, a...) \
  2153. +    { \
  2154. +        if (supermount_debug_enable) { \
  2155. +            printk ("SUPERMOUNT DEBUG (%s, %d): %s: ", \
  2156. +                __FILE__, __LINE__, __FUNCTION__); \
  2157. +            printk (f, ## a); \
  2158. +        } \
  2159. +    }
  2160. +#else
  2161. + #define supermount_debug(f, a...)    /**/
  2162. +#endif
  2163. +
  2164. +/*
  2165. + * Special inodes numbers
  2166. + */
  2167. +#define SUPERMOUNT_HIDDEN_INO         0    /* Hidden inode for
  2168. +                           sub-mounting */
  2169. +#define SUPERMOUNT_ROOT_INO         1    /* Root inode */
  2170. +
  2171. +/*
  2172. + * The supermount superblock magic number
  2173. + */
  2174. +#define SUPERMOUNT_SUPER_MAGIC    0x9fa1
  2175. +
  2176. +#ifdef __KERNEL__
  2177. +/*
  2178. + * Function prototypes
  2179. + */
  2180. +
  2181. +/*
  2182. + * Ok, these declarations are also in <linux/kernel.h> but none of the
  2183. + * supermount source programs needs to include it so they are duplicated here.
  2184. + */
  2185. +#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)
  2186. +# define NORET_TYPE    __volatile__
  2187. +# define ATTRIB_NORET  /**/
  2188. +# define NORET_AND     /**/
  2189. +#else
  2190. +# define NORET_TYPE    /**/
  2191. +# define ATTRIB_NORET  __attribute__((noreturn))
  2192. +# define NORET_AND     noreturn,
  2193. +#endif
  2194. +
  2195. +/* How to test if a supermount filesystem is active or not: */
  2196. +static inline int subfs_is_active(struct super_block *sb)
  2197. +{
  2198. +    /* The subfs is deemed inactive iff only the root is open, and
  2199. +           the its i_count is one.  */
  2200. +    return (sb->u.supermount_sb.s_state != SUPERMOUNT_UNMOUNTED &&
  2201. +        (sb->u.supermount_sb.s_opencount > 1 ||
  2202. +         sb->u.supermount_sb.s_undermount->i_mount->i_count > 1));
  2203. +}
  2204. +
  2205. +/* How to test if an inode is obsolete: */
  2206. +static inline int inode_is_obsolete(struct inode *inode)
  2207. +{
  2208. +    return (inode->u.supermount_i.i_sb_version !=
  2209. +        inode->i_sb->u.supermount_sb.s_version);
  2210. +}
  2211. +
  2212. +/* Manage the subfs dirty flag */
  2213. +static inline void mark_subfs_dirty(struct super_block *sb)
  2214. +{
  2215. +    sb->u.supermount_sb.s_dirty = 1;
  2216. +}
  2217. +static inline void mark_subfs_clean(struct super_block *sb)
  2218. +{
  2219. +    sb->u.supermount_sb.s_dirty = 0;
  2220. +}
  2221. +static inline int subfs_is_dirty(struct super_block *sb)
  2222. +{
  2223. +    return (sb->u.supermount_sb.s_dirty);
  2224. +}
  2225. +
  2226. +/* inode.c */
  2227. +extern struct inode * subiget(struct inode *);
  2228. +extern void supermount_iopen(struct inode *);
  2229. +extern void supermount_iclose(struct inode *);
  2230. +extern void supermount_go_inactive(struct super_block *);
  2231. +extern struct inode * supermount_attach(struct super_block *, struct inode *);
  2232. +extern void supermount_read_inode (struct inode *);
  2233. +extern void supermount_write_inode (struct inode *);
  2234. +extern void supermount_put_inode (struct inode *);
  2235. +extern int supermount_permission (struct inode *, int mask);
  2236. +
  2237. +/* namei.c */
  2238. +extern void supermount_release (struct inode *, struct file *);
  2239. +extern int supermount_lookup (struct inode *,const char *, int, struct inode **);
  2240. +extern int supermount_create (struct inode *,const char *, int, int,
  2241. +                  struct inode **);
  2242. +extern int supermount_mkdir (struct inode *, const char *, int, int);
  2243. +extern int supermount_rmdir (struct inode *, const char *, int);
  2244. +extern int supermount_unlink (struct inode *, const char *, int);
  2245. +extern int supermount_symlink (struct inode *, const char *, int, const char *);
  2246. +extern int supermount_link (struct inode *, struct inode *, const char *, int);
  2247. +extern int supermount_mknod (struct inode *, const char *, int, int, int);
  2248. +extern int supermount_rename (struct inode *, const char *, int,
  2249. +                  struct inode *, const char *, int, int);
  2250. +
  2251. +/* super.c */
  2252. +extern void supermount_error (struct super_block *, const char *, const char *, ...)
  2253. +    __attribute__ ((format (printf, 3, 4)));
  2254. +extern NORET_TYPE void supermount_panic (struct super_block *, const char *,
  2255. +                   const char *, ...)
  2256. +    __attribute__ ((NORET_AND format (printf, 3, 4)));
  2257. +extern void supermount_warning (struct super_block *, const char *, const char *, ...)
  2258. +    __attribute__ ((format (printf, 3, 4)));
  2259. +extern void supermount_put_super (struct super_block *);
  2260. +extern void supermount_write_super (struct super_block *);
  2261. +extern int supermount_remount (struct super_block *, int *, char *);
  2262. +extern struct super_block * supermount_read_super (struct super_block *,void *,int);
  2263. +extern void supermount_statfs (struct super_block *, struct statfs *, int);
  2264. +extern int supermount_media_check (struct super_block *);
  2265. +extern int supermount_check_inode (struct inode *);
  2266. +
  2267. +/* dir.c */
  2268. +extern struct inode_operations supermount_dir_iops;
  2269. +extern struct inode_operations supermount_root_iops;
  2270. +
  2271. +/* inode.c */
  2272. +extern struct inode_shadow_operations supermount_shadow_iops;
  2273. +
  2274. +/* file.c */
  2275. +/* extern struct inode_operations supermount_shadow_file_iops; */
  2276. +
  2277. +/* symlink.c */
  2278. +extern struct inode_operations supermount_symlink_iops;
  2279. +
  2280. +#endif    /* __KERNEL__ */
  2281. +
  2282. +#endif    /* _LINUX_SUPERMOUNT_FS_H */
  2283. Index: linux/include/linux/supermount_fs_i.h
  2284. diff -u linux/include/linux/supermount_fs_i.h:1.1 linux/include/linux/supermount_fs_i.h:1.1.4.1
  2285. --- linux/include/linux/supermount_fs_i.h:1.1    Mon Feb 26 17:55:22 1996
  2286. +++ linux/include/linux/supermount_fs_i.h    Sat Nov  9 17:27:49 1996
  2287. @@ -0,0 +1,23 @@
  2288. +/*
  2289. + *  linux/include/linux/supermount_fs.h
  2290. + *
  2291. + *  In-core inode structure for the dynamic remounting of removable media
  2292. + *
  2293. + *  Copyright (C) 1995
  2294. + *  Stephen Tweedie (sct@dcs.ed.ac.uk)
  2295. + *
  2296. + */
  2297. +
  2298. +#ifndef _LINUX_SUPERMOUNT_FS_I_H
  2299. +#define _LINUX_SUPERMOUNT_FS_I_H
  2300. +
  2301. +struct supermount_inode_info {
  2302. +    struct inode *    i_hidden;
  2303. +    int        i_sb_version;
  2304. +    int        i_subino;
  2305. +    int        i_counted;/* Has this inode been counted in
  2306. +                     the superblock reference counts
  2307. +                     yet? */
  2308. +};
  2309. +
  2310. +#endif    /* _LINUX_SUPERMOUNT_FS_I_H */
  2311. Index: linux/include/linux/supermount_fs_sb.h
  2312. diff -u linux/include/linux/supermount_fs_sb.h:1.1 linux/include/linux/supermount_fs_sb.h:1.1.4.1
  2313. --- linux/include/linux/supermount_fs_sb.h:1.1    Mon Feb 26 17:55:22 1996
  2314. +++ linux/include/linux/supermount_fs_sb.h    Sat Nov  9 17:27:49 1996
  2315. @@ -0,0 +1,44 @@
  2316. +/*
  2317. + *  linux/include/linux/supermount_sb_fs.h
  2318. + *
  2319. + *  In-core superblock struct for the dynamic remounting of removable media
  2320. + *
  2321. + *  Copyright (C) 1995
  2322. + *  Stephen Tweedie (sct@dcs.ed.ac.uk)
  2323. + *
  2324. + */
  2325. +
  2326. +#ifndef _LINUX_SUPERMOUNT_FS_SB_H
  2327. +#define _LINUX_SUPERMOUNT_FS_SB_H
  2328. +
  2329. +typedef enum {
  2330. +    SUPERMOUNT_UNMOUNTED,    /* No media mounted */
  2331. +    SUPERMOUNT_SUSPENDED,    /* Mounted but suspended because 
  2332. +                   no files open */
  2333. +    SUPERMOUNT_ONLINE,    /* Mounted and active */
  2334. +} sm_state_t;
  2335. +
  2336. +/*
  2337. + * supermount super-block data in memory
  2338. + */
  2339. +struct supermount_sb_info {
  2340. +    sm_state_t    s_state;
  2341. +    int        s_version;    /* Used to indicate obsolete inodes */
  2342. +    mode_t        s_default_mode;    /* Default mode for supermount root */
  2343. +
  2344. +    const char *    s_type;        /* Type of fs to be sub-mounted */
  2345. +    const char *    s_devname;    /* Where to mount the subfs */
  2346. +    int        s_mflags;    /* Flags to pass when mounting subfs */
  2347. +    const char *    s_data;        /* Data to pass when mounting subfs */
  2348. +
  2349. +    struct inode *    s_undermount;    /* Mount point for subfs */
  2350. +    struct super_block * s_subfs;    /* The submounted fs sb */
  2351. +    int        s_opencount;    /* Refcount of opened inodes
  2352. +                       (an inode in use as cwd
  2353. +                       does not count as open) */
  2354. +    
  2355. +    /* Flags */
  2356. +    int        s_dirty : 1;    /* Do we need to fsync() the subfs? */
  2357. +};
  2358. +
  2359. +#endif    /* _LINUX_SUPERMOUNT_FS_SB_H */
  2360.